• GCD


    题目链接:https://vjudge.net/problem/UVA-11426

    题目大意: 给出整数n∈[2,4000000],求解∑gcd(i,j),其中(i,j)满足1≤i<j≤n.

    的确没有想到是欧拉函数,这怎么会想到欧拉函数呢?  又不是要我们求所有gcd为1的个数  那些gcd不为1的怎么办呢?  当时怎么就没想到呢  除过去不就变为1了吗  自己是真的菜。。。  

    还是要多做题,把思维开阔起来!!!

    思路在代码中  直接看代码:

    /**
    欧拉函数三个性质
    是素数的话  欧拉函数值等于它本身-1
    如果a是素数 b%a==0  则phi[b*a]=phi[b]*a
    如果b%a!=0  则phi[b*a]=phi[b]*phi[a]
    */
    #include<iostream>
    #include<cstdio>
    using namespace std;
    typedef long long LL;
    const int maxn=4e6+50;
    LL N;
    LL phi[maxn],vis[maxn],p[maxn];//欧拉函数值  是否是素数  存素数
    LL f[maxn],ans[maxn];
    void Init()//求欧拉函数值
    {
        phi[1]=1;
        int num=0;
        for(int i=2;i<maxn;i++)
        {
            if(!vis[i])//是素数
            {
                p[num++]=i;
                phi[i]=i-1;//素数的欧拉函数值就等于它的值-1
            }
            for(int j=0;j<num&&p[j]*i<maxn;j++)
            {
                vis[p[j]*i]=true;//肯定不是素数
                if(i%p[j]==0)
                {
                    phi[i*p[j]]=p[j]*phi[i];
                    break;
                }
                else phi[i*p[j]]=phi[i]*phi[p[j]];
            }
        }
    
    //    for(int i=1;i<=10;i++) cout<<i<<":"<<phi[i]<<" ";
        return ;
    }
    /** 假设n等于4
    (1,2) (2,3) (3,4)
    (1,3) (2,4)
    (1,4)
    
    假设f[n]=(1,n)+(2,n)+···(n-1,n)
    则 ans=f[2]+f[3]+···+f[n]  所以我们要求的就是f[n]
    
    假设 gcd(1,n) gcd(2,n)  ···  gcd(n-1,n)中等于i的有si个
    那么gcd(s1,n)=i  gcd(s2,n)=i  gcd(si,n)=i
    则 gcd(s1/i,n/i)=1  gcd(s2/i,n/i)=1 gcd(si/i,n/i)=1
    这岂不是转换成了 总个数phi[n/i]的情形了  所以f[n]=i*phi[n/i]
    
    */
    void solve()//存f[n]
    {
        phi[1]=0;
        for(int i=1;i<maxn;i++)//遍历i的值  同时得到f[n]的部分值
        {
            for(int j=i;j<maxn;j+=i)//遍历n的值
            {
                f[j]+=i*phi[j/i];
            }
        }
        for(int i=2;i<maxn;i++) ans[i]=ans[i-1]+f[i];
        return ;
    }
    int main()
    {
        Init();
        solve();
        //while(scanf("%lld",&N)!=EOF)
        while(cin>>N)
        {
            if(N==0) break;
            cout<<ans[N]<<endl;
            //printf("%lld
    ",ans[N]);
        }
        return 0;
    }
    当初的梦想实现了吗,事到如今只好放弃吗~
  • 相关阅读:
    UI测试
    软件测试用例详解(转载)
    Mac设置命令别名
    CentOS7 开启免密登陆
    使用systemctl命令管理服务mysql
    Redis学习笔记02--主从数据库配置
    CentOS使用dnf安装Redis
    CentOS 7 防火墙设置
    Redis学习笔记01---配置文件
    CentOS7搭建Maven的Nexus私服仓库
  • 原文地址:https://www.cnblogs.com/caijiaming/p/10645488.html
Copyright © 2020-2023  润新知