• gcd+欧拉函数 (gcd打表)


    传送门

    Here GCD(i,j) means the greatest common divisor of integer i and integer j.

    For those who have trouble understanding summation notation, the meaning of G is given in the following code:

    输入N,求下面代码执行之后,G的值。

    G=0;

    for(i=1;i<N;i++)

    for(j=i+1;j<=N;j++)

    {

        G+=gcd(i,j);

    }

    /*Here gcd() is a function that finds the greatest common divisor of the two input numbers*/

    Input

    The input file contains at most 100 lines of inputs. Each line contains an integer N (1<N<4000001). The meaning of N is given in the problem statement. Input is terminated by a line containing a single zero.

    有多组数据,以0结尾。
    每行一个整数NOutput

    For each line of input produce one line of output. This line contains the value of G for the corresponding N. The value of G will fit in a 64-bit signed integer.


    对于每个N,输出相应的结果G。
    提示:可以枚举gcd的值,再通过欧拉函数解决。Sample Input

    10
    100
    200000
    0

    Sample Output

    67
    13015
    143295493160

    解析:

    就是让你求出

    题目大意 求下面这个

    sum_{i=1}^{i<N}sum_{j=i+1}^{j<N}GCD(i,j)

    假设f[n]=gcd(1,n)+gcd(2,n)+...gcd(n-1,n);

    那么我们要求的ans[n]=f(2)+f(3)+f(4)+...+f(n);

    所以我们只要把f[n]求出来就好了。

    对gcd(x,n)进行分类,用a[i]表示gcd(x,n)=i的x的个数,意思就是从1~n-1中有多少个x0和x一样是gcd(x0,n)=i。

    F[n]=sum _{i=1}^{m}a[i]*i; 这里的m表示i的种类数目,没有别的含义。

    举个例子F[6]=gcd(1,6)+gcd(2,6)+gcd(3,6)+gcd(4,6)+gcd(5,6);

    但是这四个我们可以给他分类

    不难发现gcd(1,6)==gcd(5,6)=1; //i=1的个数为欧拉函数φ(6);

    gcd(2,6)==gcd(4,6)=2
ightarrowgcd(1,3)=1,gcd(2,3)=1;//此处i=2的个数也就是欧拉函数φ(3)

    gcd(3,6)=3
ightarrowgcd(1,2)=1;//此处i=3的个数也就是欧拉函数φ(2);

    然后利用数目乘以最后的i

    F[6]=2*1+2*2+3*1=2+4+3=9;

    那么gcd(x,n)=i,可以化简成gcd(x/i,n/i)=1.与n/i互质的个数也就是欧拉函数值φ(n/i);

    通过欧拉函数找到了个数,那么这个公式不就出来了吗?

    F[n]=i*varphi [n/i]    i 表示这一类的权值,φ(n/i)则表示这一类的个数

    所以最终的答案

    ans[n]=ans[n-1]+F[n];

    就是说:

     转自:

    #include<iostream>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    const int maxn=4e6+10000;
    ll ol[maxn];
    ll prime[maxn];
    ll f[maxn];
    ll sum[maxn]; 
    int cnt=0;
    void inint(){
        ol[1]=1; 
        for(int i=2;i<maxn;i++){
            if(!ol[i]) ol[i]=i-1,prime[++cnt]=i;
            for(int j=1;j<=cnt&&i*prime[j]<maxn;j++){
                if(i%prime[j]==0){
                    ol[i*prime[j]]=ol[i]*(prime[j]);
                    break;
                }
                else{
                    ol[i*prime[j]]=ol[i]*(prime[j]-1);
                }
            }
        }
    }
    int main(){
        inint();
        int n;
        for(int i=1;i<=maxn;i++){//f[n]代表gcd(1,n)+gcd(2,n)+...gcd(n-1,n); 
            for(int j=i+i;j<=maxn;j+=i){
                f[j]+=i*ol[j/i];
            }
        }
        sum[1]=0;
        for(int i=2;i<=maxn;i++){
            sum[i]=sum[i-1]+f[i];
        }
        while(cin>>n&&n){
            cout<<sum[n]<<endl;
        } 
    } 
    221. 龙哥的问题

    龙哥现在有一道题,要考考大家。

    给定一个整数 NN,请你求出 的值。

    输入格式

    一个整数 N

    输出格式

    一个整数表示结果。

    数据范围

    1<N<2e31

    输入样例:

    6
    

    输出样例:

    15


    这个题就是上一个的变种,但是这个题的数据范围很大n<=1e9.
    还是哪样把gcd(x,n)==i中的个数找出来,就是gcd(x/i,n/i)==1的个数
    就是i*ol[n/i],
    然后就是枚举这个i,这个i肯定是n的因子
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=5e6+100;
    int biaoji[maxn];
    int prime[maxn];
    int ol[maxn];
    int cnt=0;
    int oul(ll x){
        ll ans=x;
        for(ll i=2;i*i<=x;i++){
            if(x%i==0){
                ans=ans/i*(i-1);
                while(x%i==0){
                    x/=i;
                }
            }
        }
        if(x>1){
            ans=ans/x*(x-1);
        }
        return ans;
    }
    int main(){
        ll n;
        cin>>n;
        ll ans=0;
        for(ll i=1;i*i<=n;i++){
            if(n%i==0){
                ans+=i*oul(n/i);
                if(i*i!=n){
                    ans+=(n/i*oul(i));
                }
            }
        }
        cout<<ans<<endl;   
    
    }


  • 相关阅读:
    PNG 格式小图标的 CSS 任意颜色赋色技术
    CSS导航栏下划线跟随效果
    canvas 画表格、填数据、连线、拖拽、鼠标滚轮缩放
    【IE浏览器】GET请求防止读取缓存数据的解决方法
    JavaWeb——使用JavaBean
    数字签名——确保数据来源的可认证(鉴别)性和数据发送行为的不可否认性
    信息完整性验证技术——散列函数提供的消息认证技术
    OSI安全体系结构
    (持续更新)JavaScript
    (持续更新)SVN使用总结
  • 原文地址:https://www.cnblogs.com/lipu123/p/13912207.html
Copyright © 2020-2023  润新知