首页 > 代码库 > bzoj 3994: [SDOI2015]约数个数和

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]约数个数和