bzoj 3529
非常好的一道莫比乌斯反演题,对提升自己的能力有很大帮助。
首先我们分析一下题意:题意让我们求,其中
那么我们首先对后面的式子进行一下变形,变形过程详见https://blog.csdn.net/lleozhang/article/details/89093689
于是最后变成了这个样子:
但是这个式子还是不好,所以我们改变一下枚举顺序,先枚举d
于是上式改为:
可以发现右侧的式子是一个反演的形式,于是记
于是原式=
先预处理出每个数的约数和(线性筛),然后利用数论分块+前缀和计算即可
等等,难道就这么简单?
当然不会了!!!
再仔细想想,我们上面的过程根本没有管a啊!
由于对k是有要求的,所以我们在预处理的时候如果不知道询问中的a,就没有办法确认对于每个d,哪个k是可用的!
那怎么办?
离线!
我们先将所有询问按照a从小到大排序,这样前面的询问所能用到的k后面的询问一定也可以用,这样我只需要每次将因为a变大而变得可用的k加入即可!
可是我们的要求是,所以仅仅对a排序是不够的,由于约数和并不具有单调性,所以我们还要对约数和排序,然后对于每个询问,将新变得合法的k对应地累计进f(d)就可以了
由于这是一个动态的过程,使用树状数组维护f的前缀和,这样就既支持修改,又支持求前缀和了。
贴代码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define ll long long
#define mode (1ll<<31)
using namespace std;
struct Ques
{
int n,m,a,num;
}q[100005];
int pri[100005];
bool used[100005];
int mu[100005];
struct SIG
{
ll si;
int num;
}sig[100005];
int mi[100005];
ll v[100005];
ll ret[100005];
int s[100005];
int cnt=0;
int lowbit(int x)
{
return x&(-x);
}
void ins(int x,ll y)
{
while(x<=100000)
{
s[x]+=y;
x+=lowbit(x);
}
}
int get_sum(int x)
{
int ans=0;
while(x)
{
ans+=s[x];
x-=lowbit(x);
}
return ans;
}
ll pow_mul(ll x,int y)
{
ll ans=1;
while(y)
{
if(y&1)
{
ans*=(ll)x;
}
x*=x;
y/=2;
}
return ans;
}
void init()
{
mu[1]=1;
sig[1].si=1;
sig[1].num=1;
for(int i=2;i<=100000;i++)
{
if(!used[i])
{
pri[++cnt]=i;
mu[i]=-1;
sig[i].si=i+1;
sig[i].num=i;
v[i]=i+1;
mi[i]=1;
}
for(int j=1;j<=cnt&&i*pri[j]<=100000;j++)
{
used[i*pri[j]]=1;
if(i%pri[j]==0)
{
mu[i*pri[j]]=0;
ll temp=v[i]+pow_mul(pri[j],mi[i]+1);
sig[i*pri[j]].si=sig[i].si/v[i]*temp;
sig[i*pri[j]].num=i*pri[j];
mi[i*pri[j]]=mi[i]+1;
v[i*pri[j]]=temp;
break;
}
mu[i*pri[j]]=-mu[i];
sig[i*pri[j]].si=sig[i].si*(pri[j]+1);
sig[i*pri[j]].num=i*pri[j];
v[i*pri[j]]=pri[j]+1;
mi[i*pri[j]]=1;
}
}
}
bool cmp(Ques x,Ques y)
{
return x.a<y.a;
}
bool cmp1(SIG x,SIG y)
{
return x.si<y.si;
}
int solve(int x,int y)
{
if(x>y)
{
swap(x,y);
}
int ans=0;
int last=0;
for(int i=1;i<=x;i=last+1)
{
last=min(x/(x/i),y/(y/i));
ans+=(get_sum(last)-get_sum(i-1))*(x/i)*(y/i);
}
return ans;
}
int T;
inline int read()
{
int f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
T=read();
init();
int maxn=0;
for(int i=1;i<=T;i++)
{
q[i].n=read(),q[i].m=read(),q[i].a=read();
q[i].num=i;
maxn=max(maxn,max(q[i].n,q[i].m));
}
sort(q+1,q+T+1,cmp);
sort(sig+1,sig+100001,cmp1);
int las=1;
for(int i=1;i<=T;i++)
{
while(sig[las].si<=q[i].a&&las<=100000)//枚举k
{
for(int j=1;j*sig[las].num<=maxn;j++)//枚举倍数
{
ins(j*sig[las].num,sig[las].si*mu[j]);
}
las++;
}
ret[q[i].num]=solve(q[i].n,q[i].m)&2147483647;
}
for(int i=1;i<=T;i++)
{
printf("%d\n",ret[i]);
}
return 0;
}
bzoj 3529的更多相关文章
- 【莫比乌斯反演】关于Mobius反演与gcd的一些关系与问题简化(bzoj 2301 Problem b&&bzoj 2820 YY的GCD&&BZOJ 3529 数表)
首先我们来看一道题 BZOJ 2301 Problem b Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd( ...
- 【BZOJ 3529】 [Sdoi2014]数表 (莫比乌斯+分块+离线+树状数组)
3529: [Sdoi2014]数表 Description 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有 ...
- BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]
3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1399 Solved: 694[Submit][Status] ...
- BZOJ 3529 数表(莫比乌斯反演)
http://www.lydsy.com/JudgeOnline/problem.php?id=3529 思路:令F(i)为i的约数和, 1<=x<=n,1<=y<=m G(i ...
- bzoj 3529 数表
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3529 题目大意:令F(i)为i的约数和,多次询问对于1<=x<=n,1< ...
- ●BZOJ 3529 [Sdoi2014]数表
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3529 题解: 莫比乌斯反演. 按题目的意思,令$f(i)$表示i的所有约数的和,就是要求: ...
- BZOJ 3529 数表(莫比乌斯+树状数组)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3529 题意:有一张n×m的数表,其第i行第j列的数值为能同时整除i和j的所有自然数 ...
- bzoj 3529: [Sdoi2014]数表
#include<cstdio> #include<iostream> #include<algorithm> #define M 200009 //#define ...
- 【BZOJ 3529】【SDOI 2014】数表
看Yveh的题解,这道题卡了好长时间,一直不明白为什么要······算了当时太naive我现在都不好意思说了 #include<cstdio> #include<cstring> ...
- bzoj 3529 数表 莫比乌斯反演+树状数组
题目大意: 有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为能同时整除i和j的所有自然数之和.给定a,计算数表中不大于a的数之和. ...
随机推荐
- (3)java数据结构--有枚举 属性
java中的数据结构 - 南风顾 - 博客园http://www.cnblogs.com/tingxuelou/p/6686143.html 线性表,链表,哈希表是常用的数据结构,在进行Java开发时 ...
- 【MySQL】CentOS下安装及搭建主从复制
CentOS下安装MySQL 1,wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm 2,rpm -ivh m ...
- Linux就该这么学(1)-系统概述(学习笔记)
一.热门的Linux系统开源许可协议 GNU GPL(GNU General Public License,GNU 通用公共许可证) BSD(Berkeley Software Distributio ...
- GPU Tips
<1> Basic #include <stdio.h> #include <cuda_runtime.h> #include <device_launch_ ...
- Focal Loss理解
1. 总述 Focal loss主要是为了解决one-stage目标检测中正负样本比例严重失衡的问题.该损失函数降低了大量简单负样本在训练中所占的权重,也可理解为一种困难样本挖掘. 2. 损失函数形式 ...
- sublime修改侧边栏字体
安装了sublime的material主题后,侧边栏的字体特别小,设置方法如下: 安装插件 用上面的插件打开 Material-Theme.sublime-theme 如下 { "class ...
- liunx中的iptables
作者:邓聪聪 iptables的入站端口放行策略: iptables -A INPUT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT ...
- 设计模式C++学习笔记之一(Strategy策略模式)
无意中,从网上下到一本电子书<24种设计模式介绍与6大设计原则>,很好奇这里有24种设计模式,印象中GOF写的<设计模式>(Design Patterns),好像只有23种吧. ...
- 数据库之删除表数据drop、truncate和delete的用法
数据库中删除表数据的关键字,最常用的可能就是delete了,另外其实还有drop和truncate两个关键字. 老大:drop 命令格式:drop table tb ---tb表示数据表的名字,下 ...
- Laravel 5.2--git冲突error: Your local changes to the following files would be overwritten by merge:
今天在服务器上git pull是出现以下错误: error: Your local changes to the following files would be overwritten by mer ...