本来想用容斥原理,但我居然不造还有欧拉函数这个神奇的东西,果然还是太弱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 }