1. 程式人生 > >洛谷 P2568 GCD

洛谷 P2568 GCD

ble 條件 oid 數組 %d ++ void break tps

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. }

洛谷 P2568 GCD