最大公约数之和欧拉函数

Posted 00isok

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大公约数之和欧拉函数相关的知识,希望对你有一定的参考价值。

欧拉函数的基本性质详解(见该链接):https://blog.csdn.net/w144215160044/article/details/51158735

 

                                                       最大公约数和

                                                     发布时间: 2018年3月27日 09:20   时间限制: 1000ms   内存限制: 128M

已知n(1≤n≤2000000000),令g(n)=gcd(1,n)+gcd(2,n)+…+gcd(n,n),输出g(n)的值。gcd(a,b)表示a与b的最大公约数。 

输入包含若干个数据,每行一个数n。
数据组数不超过50000 。

对于每个输入的n,在一行内输出g(n)。

2
6
3
15

请使用scanf和printf输入与输出。

数据比较多,容易超时!

 

#include<algorithm>              //此代码暂时还不是很理解,先记录着吧
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<iostream>
#define M 44721
#define N 1000010
using namespace std;
int pNum, prime[M];        
bool f[M];
int num = 101;
void fun()//用素数筛选法建立素数表,从1到44721,因为n最大20 0000 0000,到根号n即可
{                                               
    int i, j;
    pNum = 0;
    memset(f, true, sizeof(f));
    f[0] = f[1] = false;
    for (i = 2; i <= (int)sqrt(M); i++)
    {
        if (f[i])
        {
            for (j = i * i; j<M; j += i)
                f[j] = false;
        }
    }
    for (i = 2; i<M; i++)
        if (f[i])
            prime[pNum++] = i;            //先打表,将1-2000000000之间的素数全部找出来
}
long long pow1(int a, int b)//求a^b,因为数据比较大,用pow函数可以会有精度问题
{
    int i;
    long long s;
    for (i = 0, s = 1; i<b; i++)
        s *= a;
    return s;
}
long long fun1(int a)
{
    int i, s_a, s_b, cnt;
    cnt = -1;
    for (i = 0; prime[i] <= (int)sqrt(a); i++)
    {
        if (a%prime[i] == 0)
        {
            a /= prime[i];
            cnt = prime[i];
            s_a = prime[i];
            s_b = 1;
            while (a%prime[i] == 0)
            {
                cnt *= prime[i];
                a /= prime[i];
                s_b++;
            }
            break;
        }
    }
    if (cnt == -1)//第二种情况
        return (long long)a * 2 - 1;//注意int64的强制转换
    if (a == 1)//第三种情况
        return pow1(s_a, s_b - 1)*(s_b*(s_a - 1) + s_a); //第一种情况
    return fun1(cnt)*fun1(a);
}
int main()
{
    int n;
    fun();
    while (scanf("%d", &n) != EOF)
        printf("%lld\n", fun1(n));
    return 0;
}

 

2018-04-05

以上是关于最大公约数之和欧拉函数的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1040 最大公约数之和(欧拉函数)

51nod 1040最大公约数和(欧拉函数)

51Nod 1239 欧拉函数之和

UVA 11426 (欧拉函数&&递推)

欧拉函数之和 51Nod - 1239

1040 最大公约数之和