hdu 3501 欧拉函数的拓展

问题描述:
给出一个N,求1..N中与N互质的数的和

if gcd(n,i)=1 then gcd(n,n-i)=1 (1<=i<=n)

反证法:
        如果存在K!=1使gcd(n,n-i)=k,那么(n-i)%k==0
        而n%k=0
         那么必须保证i%k=0
        k是n的因子,如果i%k=0那么gcd(n,i)=k,矛盾出现;
        于是问题变的非常简单: ANS=N*phi(N)/2
        i,n-i总是成对出现,并且和是n
       于是可能就有人问了,如果存在n-i=i那不是重复计算?
        答案是不会
        因为:
                n=2*i->i=n/2
        1.如果n是奇数,那么n!=2*i,自然也不存在n-i=i和重复计算之说
        2.如果n是偶数,n=2*i成立,gcd(n,n/2)必然为n的一个因子,这个因子为1当且仅当n==2
        于是对于n>2的偶数,绝对不存在gcd(n,n/2)=1所以更别说什么重复计算了
        对于n==2
        ans=2*1/2=1,正好也满足
        所以得到最终公式:
       ans=N*phi(N)/2
---------------------以上内容转载自_______________________
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define MOD 1000000007

using namespace std;

long long euler ( long long num )
{
    long long res = num;
    for ( long long i = 2 ; i*i<=num ; i++ )
    {
            if ( num %i == 0 )
            {
                res -= res/i;
                while (  num%i==0 ) num /= i;
            }
    }
    if ( num > 1 ) res -= res/num;
    return res;
}

int main ( )
{
    long long ans;
    while ( ~scanf ( "%lld" , &ans ) ,ans )
        printf ( "%lld\n" , (ans*(ans-1L) /2L - euler(ans)*ans/2L)%MOD );
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值