bzoj 3994: [SDOI2015]约数个数和
Posted ws_ccd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 3994: [SDOI2015]约数个数和相关的知识,希望对你有一定的参考价值。
本蒟蒻不会23333(SDOI总是这种sb题,感觉很快就回家“耕耘”了。)
%%%fqk http://blog.csdn.net/phenix_2015/article/details/50790860
1 #include<bits/stdc++.h> 2 #define N 100005 3 #define M 10000005 4 #define LL long long 5 #define inf 0x3f3f3f3f 6 using namespace std; 7 inline int ra() 8 { 9 int x=0,f=1; char ch=getchar(); 10 while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();} 11 while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();} 12 return x*f; 13 } 14 int mo[N],prime[N],f[N],cnt; 15 LL d[N]; 16 bool vis[N]; 17 void mobius() 18 { 19 mo[1]=d[1]=1; 20 for (int i=2; i<=50000; i++) 21 { 22 if (!vis[i]) prime[++cnt]=i,mo[i]=-1,d[i]=2,f[i]=1; 23 for (int j=1; j<=cnt && i*prime[j]<=50000; j++) 24 { 25 vis[prime[j]*i]=1; 26 if (i%prime[j]) 27 { 28 mo[i*prime[j]]=-mo[i]; 29 f[i*prime[j]]=1; 30 d[i*prime[j]]=d[i]*2; 31 } 32 else 33 { 34 mo[i*prime[j]]==0; 35 f[i*prime[j]]=f[i]+1; 36 d[i*prime[j]]=d[i]/(f[i]+1)*(f[i]+2); 37 } 38 } 39 } 40 for (int i=1; i<=50000; i++) d[i]+=d[i-1],mo[i]+=mo[i-1]; 41 } 42 int main() 43 { 44 mobius(); int T=ra(); 45 while (T--) 46 { 47 int n=ra(),m=ra(); if (n>m) swap(n,m); 48 LL ans=0; 49 for (int i=1,pos; i<=n; i=pos+1) 50 { 51 pos=min(n/(n/i),m/(m/i)); 52 ans+=(LL)(mo[pos]-mo[i-1])*d[n/i]*d[m/i]; 53 } 54 printf("%lld\n",ans); 55 } 56 return 0; 57 }
以上是关于bzoj 3994: [SDOI2015]约数个数和的主要内容,如果未能解决你的问题,请参考以下文章
bzoj3994: [SDOI2015]约数个数和(莫比乌斯反演+分块)