您的位置:首页 > 其它

【BZOJ】2693: jzptab 莫比乌斯反演

2018-01-16 08:34 411 查看

【题意】2154: Crash的数字表格 莫比乌斯反演,多组询问,T<=10000。

【算法】数论(莫比乌斯反演)

【题解】由上一题,

$ans=\sum_{g\leq min(n,m)}g\sum_{d\leq min(n/g,m/g)}\mu (d)*d^2*sum(n/gd,m/gd)$

令T=gd

$ans=\sum_{T\leq min(n,m)}sum(n/T,m/T)*T\sum_{d|T}\mu (d)*d$

后面部分由积性函数的乘积和约数和也是积性函数可以线性筛得出。

当i%prime[j]=0时,相对于i多出来的因子必然由重复因子即μ(d)=0,故无视即可。

复杂度O(n+T√n)。

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e7,maxn=1e7+10,MOD=1e8+9;//
int s[maxn],sum[maxn],prime[maxn],tot,n,m;
bool mark[maxn];
int SUM(int x,int y){return 1ll*(1ll*x*(x+1)/2%MOD)*(1ll*y*(y+1)/2%MOD)%MOD;}
int main(){
s[1]=1;sum[1]=1;
for(int i=2;i<=N;i++){
if(!mark[i]){s[prime[++tot]=i]=(1-i+MOD)%MOD;}
for(int j=1;j<=tot&&i*prime[j]<=N;j++){
mark[i*prime[j]]=1;
if(i%prime[j]==0){s[i*prime[j]]=s[i];break;}
s[i*prime[j]]=1ll*s[i]*s[prime[j]]%MOD;
}
sum[i]=(1ll*i*s[i]+sum[i-1])%MOD;
}
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
int z=min(n,m),pos=0,ans=0;
for(int i=1;i<=z;i=pos+1){
pos=min(n/(n/i),m/(m/i));
ans=(ans+1ll*(sum[pos]-sum[i-1]+MOD)*SUM(n/i,m/i)%MOD)%MOD;
}
printf("%d\n",ans);
}
return 0;
}
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: