bzoj 2818

本来想用容斥原理,但我居然不造还有欧拉函数这个神奇的东西,果然还是太弱orz

题解orzlsj:

要求gcd(x, y) = p (1 <= x, y <= n, p为质数 ) 的数对(x, y)个数.我们枚举素数p, 令x' = x / p, y' = y / p, 则只须求  f(p) = gcd(x', y') = 1的数对(x', y')个数(1 <= x', y' <= n / p), 显然f(p) = (∑ phi(x')) * 2 - 1(1 <= x' <= n / p). 所以最后答案为 ∑f(p)

 1 #include<bits/stdc++.h>
 2 #define inc(i,l,r) for(i=l;i<=r;i++)
 3 #define dec(i,l,r) for(i=l;i>=r;i--)
 4 #define inf 1e9
 5 #define NM 10000000+5
 6 #define mem(a) memset(a,0,siezof(a))
 7 long long d[NM],ans;
 8 int n,i,j,p[NM],m;
 9 bool v[NM];
10 void init(){
11     d[1]=1;
12     inc(i,2,n){
13         if(!v[i]){
14             p[++m]=i;
15             d[i]=i-1;
16         }
17         inc(j,1,m){
18             if(i*p[j]>n)break;
19             v[i*p[j]]++;
20             if(i%p[j])d[i*p[j]]=d[i]*d[p[j]];
21             else d[i*p[j]]=d[i]*p[j];
22         }
23     }
24 }
25 int main(){
26     scanf("%d",&n);
27     init();
28     inc(i,1,n)d[i]+=d[i-1];
29     inc(i,1,m)ans+=d[n/p[i]]*2-1;
30     printf("%lld",ans);
31     return 0;
32 }
View Code

 

原文地址:https://www.cnblogs.com/onlyRP/p/4717424.html