P2568 GCD

#$Description$ 给定$n$,求$1<=x,y<=n$满足$gcd(x,y)=p$(其中$p$为质数)的$(x,y)$有多少对 #$Solution$ 乍一看是莫比乌斯反演,~~虽然我不会莫比乌斯反演~~ 其实这道题是简单的筛法+欧拉函数 $ans=\sum\limits_{i=1}^n\sum\limits_{j=1}^n[gcd(i,j)==p]$ $gcd$常用技巧 $=\sum\limits_{p\in prime}\sum\limits_{i=1}^{\lfloor \frac{n}{p} \rfloor}\sum\limits_{j=1}^{\lfloor \frac{n}{p} \rfloor}[gcd(i,j)==1]$ 因为$i,j$是等效的,所以只用将$j$枚举到$i$即可,保证$j #include #include #define maxn 10000010 #define re register #define ll long long using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ll ans; int n,is_not_prime[maxn],prime[maxn],pcnt,phi[maxn]; void pre() { is_not_prime[1]=1; phi[1]=1; for(int i=1;i<=n;++i) { if(!is_not_prime[i]) { prime[++pcnt]=i; phi[i]=i-1; } for(int j=1;j<=pcnt;++j) { if(i*prime[j]>n) break; is_not_prime[i*prime[j]]=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]]; } } } int main() { n=read(); pre(); for(re int i=1;i<=pcnt;++i) { for(re int j=1;j<=n/prime[i];++j) { ans+=2*phi[j]; } ans--; } //for(re int i=1;i<=n;++i) printf("%d ",phi[i]); printf("%lld\n",ans); return 0; } ```
posted @ 2019-10-05 18:22  __Liuz  阅读(148)  评论(0)    收藏  举报