莫比乌斯真的…难推…有时间..再推吧【捂脸】
莫比乌斯反演呢,其实说的就是
变下型就是
这个可以通过预处理线性时间求出
就像这样
void mobius(){
mu[1]=1;
memset(notprime,false,sizeof(notprime));
for(int i=2;i<=50000;i++){
if(!notprime[i]) prime[++top]=i,mu[i]=-1;
for(int j=1;j<=top && prime[j]*i<=50000;j++){
notprime[prime[j]*i]=true;
if(i%prime[j]==0){
mu[i*prime[j]]=0;
break;
}mu[i*prime[j]]=-mu[i];
}
}
那么说个小例子吧
,求使
的对数 (bzoj1101/lg3455)
我们设
表示
的倍数的对数,
表示
的对数(即所求)
由莫比乌斯变形可以得到
又发现呢, 可以求(不像 哼)
因为,如果 即 ,所以就求有多少对 即可
而 都应当是k的倍数才有可能
所以
当然..这个方法吧…不太适用【捂脸】..就是…不适用于大多数题
因此..还有另一个想法【捂脸】(是不是感觉很无奈 哎呀我也没办法~)
求的就是
也就是 时个数加一,就和 很像哦
因此所求就是
又因为
就是这样【捂脸】
不过呢~
还可以更好哦~
可以分块【捂脸】
因为
最多
块,
最多
块
因此把每个相等的块(
与
相等)..找到这个块中对应的
和(可通过前缀和求出)即可~
ll f(int n,int m,int k){
if(n>m) swap(n,m);
n/=k;m/=k;
ll ans=0;
for(int i=1,last=1;i<=n;i=last+1){
last=min(n/(n/i),m/(m/i));
ans+=(ll)(mu[last]-mu[i-1])*(m/i)*(n/i);
}return ans;
}
扩展一下,a<=x<=b,c<=y<=d的时候呢
做法就是用容斥原理【捂脸】
结果就是
小女子不才,欢迎大佬们找错【捂脸】