BZOJ 3994: [SDOI2015]约数个数和3994: [SDOI2015]约数个数和 莫比乌斯反演
https://www.lydsy.com/JudgeOnline/problem.php?id=3994
https://blog.csdn.net/qq_36808030/article/details/77056706
莫比乌斯反演,我现在莫比乌斯反演都不会写不会推了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 #define LL long long 9 const int maxn=50010; 10 int mu[maxn]={},pri[maxn]={},tot=0; 11 bool v[maxn]={};LL f[maxn]={}; 12 void get_mu(int n){ 13 mu[1]=1; 14 for(int i=2;i<=n;++i){ 15 if(!v[i]){pri[++tot]=i;mu[i]=-1;} 16 for(int j=1;j<=tot&&pri[j]*i<=n;++j){ 17 int w=pri[j]*i;v[w]=1; 18 if(i%pri[j]==0){mu[w]=0;break;} 19 mu[w]=mu[i]*(-1); 20 } 21 } 22 for(int i=1;i<=n;++i){ 23 mu[i]+=mu[i-1]; 24 for(int j=1,las;j<=i;j=las+1){ 25 las=i/(i/j); 26 f[i]+=(LL)(las-j+1)*(LL)(i/j); 27 } 28 } 29 } 30 int main(){ 31 get_mu(maxn-10); 32 int T;scanf("%d\n",&T); 33 while(T-->0){ 34 int n,m; scanf("%d%d",&n,&m); 35 if(n>m)swap(n,m); 36 LL ans=0; 37 for(int i=1,las;i<=n;i=las+1){ 38 las=min(n/(n/i),m/(m/i)); 39 ans+=(LL)(mu[las]-mu[i-1])*f[n/i]*f[m/i]; 40 } 41 printf("%lld\n",ans); 42 } 43 return 0; 44 }