zoukankan      html  css  js  c++  java
  • 【洛谷P2568】GCD

    题目大意:给定整数 (N),求(1le x,yle N)(gcd(x,y)) 为素数的数对 ((x,y)) 有多少对。

    题解:

    [sum_{p in ext { prime }} sum_{i=1}^{n} sum_{j=1}^{n}[operatorname{gcd}(i, j)=p] ]

    [sum_{p in ext { prime }} sum_{i=1}^{leftlfloorfrac{n}{p} ight floor} sum_{j=1}^{leftlfloorfrac{n}{p} ight floor}[operatorname{gcd}(i, j)=1] ]

    [sum_{p in ext { prime }}left(sum_{i=1}^{leftlfloorfrac{n}{p} ight floor}left(2 sum_{j=1}^{i}[operatorname{gcd}(i, j)=1] ight)-1 ight) ]

    [sum_{p in ext { prime }}left(2 sum_{i=1}^{leftlfloorfrac{n}{p} ight floor} varphi(i)-1 ight) ]

    因此,利用线性筛求出欧拉函数的前缀和,直接枚举素数计算答案贡献即可。

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e7+10;
    
    int n,prime[maxn],tot;
    ll phi[maxn],sum[maxn];
    bool vis[maxn];
    
    void sieve(){
        phi[1]=1;
        for(int i=2;i<=n;i++){
            if(!vis[i])prime[++tot]=i,phi[i]=i-1;
            for(int j=1;i*prime[j]<=n;j++){
                vis[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]*(prime[j]-1);
                }
            }
        }
        for(int i=1;i<=n;i++)sum[i]=sum[i-1]+phi[i];
    }
    
    int main(){
        scanf("%d",&n);
        sieve();
        ll ans=0;
        for(int i=1;i<=tot;i++)ans+=(2*sum[n/prime[i]]-1);
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    UVALive 6319 暴力
    UVALive 6322 最大匹配
    uvalive 6323 状态压缩DP
    hdu 3874 树状数组
    hdu 3721 树的直径
    hdu 4258 斜率DP
    组队练习 2011年福州全国邀请赛
    FZU 2041 二分枚举
    Kafka基础教程(三):C#使用Kafka消息队列
    Kafka基础教程(二):Kafka安装
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10724648.html
Copyright © 2011-2022 走看看