zoukankan      html  css  js  c++  java
  • [俺们学校的题]伪.GCD

    GCD

    题面:

      给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对.

    思路:

      首先两个数gcd(x,y)=p为质数,那么令x=k1*p,y=k2*p,由于是最大公因数,所以有k1k2互质,那么根据每一个p我们可以构造出一些不同的k1k2(k1,k2<=n/p),于是求k1,k2可行组合就变成了求 1~n/p范围之内的互质组数。我们运用欧拉筛同时解决找p和互质组数的问题

      首先解决互质组数的问题。我们设f[i]为1~i中的互质二元组个数。则有递推式:

      f[i]=f[i-1]+2*φ(i)

      因为1~i-1我们已经计算过了,所以考虑当前的i与1~i之间组成的互质二元组个数。很显然的,个数为φ(i).欧拉筛求解。由于二元组无序,所以*2

      在欧拉筛的时候,可以同时求出质数p和φ(i).所以求出答案。

      注意在欧拉筛是从2开始,所以初始化f[1]=1;

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<fstream>
    using namespace std;
    #define ll long long
    ll phi[10000001],prm[10000001],n,cnt,f[10000001];
    bool vis[10000001];
    inline void findphi(){
        phi[1]=1,prm[1]=0;
        for (ll i=2;i<=n;++i)
        {
            if (!vis[i]) { prm[++cnt]=i, phi[i]=i-1; }
            for (ll j=1;j<=cnt && i*prm[j]<=n;++j)
            {
                vis[i*prm[j]]=1;
                if (i%prm[j]==0) { phi[i*prm[j]]=phi[i]*prm[j]; break; }
                if (i%prm[j]!=0) phi[i*prm[j]]=phi[i]*(prm[j]-1);   
            }
            f[i]=f[i-1]+2*phi[i];
        }
        return; 
    }
    int main(){
        cin>>n;
        cnt=0;
        f[1]=1;
        findphi();
        ll ans=0;
        for(int i=1;i<=cnt;++i){
            ans+=f[n/prm[i]];
        }
        cout<<ans;    
    }
  • 相关阅读:
    20145316《信息安全系统设计基础》第七周学习总结
    20145316 许心远《信息安全系统设计基础》第六周学习总结
    20145316 《信息安全系统设计基础》第五周学习总结
    20145316 《信息安全系统设计基础》第二周学习总结
    面试之关系型数据库
    面试之网络基础
    Java 并发
    Scrapy 组件的具体用法
    Scrapy 框架入门
    Spring Security 介绍与Demo
  • 原文地址:https://www.cnblogs.com/clockwhite/p/12077566.html
Copyright © 2011-2022 走看看