码迷,mamicode.com
首页 > 其他好文 > 详细

最大公约数之和【欧拉函数】

时间:2018-04-05 11:34:22      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:欧拉   void   enter   ace   代码   素数   href   lld   body   

欧拉函数的基本性质详解(见该链接):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

最大公约数之和【欧拉函数】

标签:欧拉   void   enter   ace   代码   素数   href   lld   body   

原文地址:https://www.cnblogs.com/00isok/p/8721293.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!