zoukankan      html  css  js  c++  java
  • 欧拉函数——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;
    }
  • 相关阅读:
    jQuery 基础一 样式篇
    javaJavaScript DOM
    linux 实用命令
    Linux下修改.bash_profile 文件改变PATH变量的值
    java 字符串截取的方法
    Telnet命令参考手册
    linux下dubbo调试 ---telnet命令
    【Spring Task】定时任务详解实例-@Scheduled
    Spring定时任务的几种实现
    SQL之case when then用法
  • 原文地址:https://www.cnblogs.com/helman/p/11354558.html
Copyright © 2011-2022 走看看