随笔 - 125  文章 - 0 评论 - 16 阅读 - 20666
< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

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

 

 

 

posted on   onlyRP  阅读(142)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示