洛谷 P2568 GCD
https://www.luogu.org/problemnew/show/P2568#sub
最喜欢题面简洁的题目了。
本题为求两个数的gcd是素数,那么我们将x和y拆一下,
假设p为$gcd(x,y)$,且p是一个素数,$x=a \times p , y = b \times p $。
然而要满足p的条件的话,a和b一定是互质的,满足$0 \le a,b \le \frac{n}{p} $
这样的话我们可以枚举这个质数p,将小于$\frac{n}{p}$的数,以及与它互质的数加起来。
互质的数的个数自然想到了欧拉函数,优化想加的话显然前缀和(我就琢磨了半天)
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; #define LL long long int n; int prime[1000006],tot; bool vis[10000006]; LL phi[10000006],ans; void get_phi() { phi[1]=0; for(int i=2;i<=n;i++) { if(!vis[i])prime[++tot]=i,phi[i]=i-1; for(int j=1;j<=tot&&prime[j]*i<=n;j++) { vis[prime[j]*i]=1; if(i%prime[j]==0) { phi[i*prime[j]]=phi[i]*prime[j]; break; } else phi[i*prime[j]]=phi[i]*phi[prime[j]]; } } for(int i=3;i<=n;i++)phi[i]=phi[i-1]+phi[i]; } int main() { scanf("%d",&n); get_phi(); for(int i=1;i<=tot;i++)ans+=phi[n/prime[i]]; printf("%lld",ans*2+tot);
//乘2的原因就不多说了(x,y)和(y,x)啊。
之所以再加一个tot是因为我的phi数组定义的phi[1]=0. }
除特别注明外,本站所有文章均为Manjusaka丶梦寒原创,转载请注明来自出处