BZOJ 2818GCD
转载注明出处:http://www.cnblogs.com/radioteletscope/p/7142762.html
题面:
2818: Gcd
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 5345 Solved: 2400
[Submit][Status][Discuss]
Description
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.
Input
一个整数N
Output
如题
Sample Input
4
Sample Output
4
HINT
hint
对于样例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7
令$f[i]=\sum_{d|T}^{} \mu(\frac{T}{d})$
只需线性筛出,再分块处理询问。
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 #define LL long long 5 const int maxn=10000001; 6 int mu[maxn+10],prime[maxn+10],g[maxn+10]; 7 int s[maxn+10]; 8 bool book[maxn+10]; 9 int T,n,cnt; 10 void ss() 11 { 12 mu[1]=1; 13 for(int i=2;i<=maxn;i++) 14 { 15 if(!book[i]) 16 { 17 prime[++cnt]=i; 18 mu[i]=-1; 19 g[i]=1; 20 } 21 for(int j=1;j<=cnt&&i*prime[j]<=maxn;j++) 22 { 23 book[i*prime[j]]=true; 24 if(i%prime[j]) 25 mu[i*prime[j]]=-mu[i],g[i*prime[j]]=mu[i]-g[i]; 26 else 27 { 28 mu[i*prime[j]]=0; 29 g[i*prime[j]]=mu[i]; 30 break; 31 } 32 } 33 } 34 s[0]=0; 35 for(int i=1;i<=maxn;i++) 36 s[i]=s[i-1]+g[i]; 37 } 38 LL caculate() 39 { 40 LL ans=0,last; 41 for(int i=1;i<=n;i=last+1) 42 { 43 last=n/(n/i); 44 ans+=(LL)(s[last]-s[i-1])*(n/i)*(n/i); 45 } 46 return ans; 47 } 48 int main() 49 { 50 ss(); 51 scanf("%d",&n); 52 printf("%lld\n",caculate()); 53 }