• 欧拉函数——POJ-2480


    题目链接

    题目要你求sigma gcd(i,N)  1<=i<=N

    首先要知道一个式子gcd(i,N)=p  =>  gcd(i/p,N/p)=1

    以N=12举例

    gcd=1的个数就是与12互质的数字的个数,也就是12的欧拉函数值,12与1,5,7,11的gcd

    gcd=2的个数包含了12/2=6的欧拉函数值,也就是12与2,10的gcd

    gcd=3的个数包含了12/3=4的欧拉函数值,也就是12与3,9的gcd

    这样从i=1,i*i<=n,找到n%i==0的所有i*euler(n/i)就已经找到了大部分的gcd了

    剩下的则是有gcd包含了几个素数相乘

    可以知道gcd(i,N)全部都是N的因子,公约数嘛

    这些因子有些比√n大,有些比√n小

    通过之前的式子,我们的思路是找到N所有可能的gcd=P,累加P*euler(N/P)

    在我们循环i=1,i*i<=n 找到N%i==0的过程中,找到的这个i因子是小等于√N的

    但是如果i*i<N,那么N/i 一定大于√N并且也是N的因子

    所以循环里找到这些对应有两个因子的i 进行累加

    题目代码

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    typedef long long LL;
    LL euler(LL n){
        LL ans=n;
        for(LL i=2;i*i<=n;i++){
            if(n%i==0){
                ans=ans/i*(i-1);
                while(n%i==0)
                    n/=i;
            }
        }
        if(n>1)
            ans=ans/n*(n-1);
        return ans;
    }
    int main(){
        LL n;
        while(~scanf("%lld",&n)){
            LL sum=0;
            for(LL i=1;i*i<=n;i++)
            if(n%i==0){
                sum+=i*euler(n/i);
                if(i*i<n)sum+=(n/i)*euler(i);
            }
            printf("%lld
    ",sum);
        }
        return 0;
    }
  • 相关阅读:
    usb 安装系统
    跨站请求伪造攻击的基本原理与防范
    解决hexo神烦的DTraceProviderBindings MODULE_NOT_FOUND
    我知道
    MAC 重置MySQL root 密码
    线性变换与独立观察的期望和方差
    最小二乘法
    卡方检验中自由度的计算
    关于置信水平,求区间的简便算法
    独立观察与线性变换方差 均值计算
  • 原文地址:https://www.cnblogs.com/helman/p/11354558.html
Copyright © 2020-2023  润新知