POJ 2480 Longge's problem

2016暑期集训2-I

POJ 2480 Longge’s problem

数论,欧拉函数变形

传送门:HustOJ

传送门:POJ


题意

给了N(最大2^31),求∑gcd(i, N) ,1<=i <=N。


思路

欧拉函数可知,在1···N中,gcd(i,N) = 1, 的个数的等于φ(N),因为模的特性,取模和乘法可以交换运算,所以在1···N中,gcd(i,N) = x, 的个数的等于φ(N / x)。可以写几个例子推一下。所以,f(N)=∑x*φ(N/x),x | N (x是N的约数)。对于每个N的约数(不仅仅是质因数!),求一下φ(N/x)的值。这里有几点注意:

  • 这个欧拉函数不能打表,因为2^31太大了,打不下,需要一个个的求。
  • 求约数的过程不能用O(n)的,要用O(根号n)的,否则会超时。x是约数,如果x*x不等于N,那么N/x也是约数。

代码

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<iomanip>

using namespace std;
typedef long long ll;

ll phi ( ll n )
{
    ll tn = n;
    ll phi = n;
    for ( ll i = 2; ( i*i <= n ); i++ )
    {
        if ( tn % i == 0 )
        {
            phi = phi*( i - 1 ) / i ;
        }
        while ( tn % i == 0 )
        {
            tn /= i;
        }
    }
    if ( tn > 1 )
    {
        phi = phi*( tn - 1 ) / tn ;
    }
    return phi;
}
int main ( )
{
    ll n;
    while ( ~scanf ( "%lld" , &n ) )
    {
        ll res = 0;
        for ( ll i = 1; i*i <= n; i++ )
        {
            if ( n%i == 0 )
            {
                if ( i*i == n )
                {
                    res += ( i*phi ( n / i ) );
                }
                else
                {
                    res += ( i*phi ( n / i ) + ( n / i )*phi ( i ) );
                }
            }
        }
        printf ( "%lld\n" , res );
    }

    //system ( "pause" );
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值