http://acm.hdu.edu.cn/showproblem.php?pid=3501

继续欧拉函数,关键点是求小于n且与n互质的数的和。

公式是Eular(n)*n/2,简略证明如下:

原问题等价于一个数n,如果a与它互质,那么n-a也与它互质;

反证法,假设n与a互质,n与n-a不互质

设n和n-a的最大公约数为m,则n=p*m,n-a=q*m

所以a=(p-q)*m,推导出a和n有公约数m,与假设矛盾

View Code
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <map>
#include <algorithm>
using namespace std;
__int64 Eular(__int64 n)
{
    __int64 ret=n;
    for(int i=2;i*i<=n;i++)
        if(n%i==0)
        {
            ret-=ret/i;
            while(n%i==0)n/=i;
            if(n==1)break;
        }
    if(n!=1)ret-=ret/n;
    return ret;
}
int main()
{
    __int64 n;
    while(scanf("%I64d",&n),n)
        printf("%I64d\n",((n+1)*n/2-n-Eular(n)*n/2)%1000000007);
    return 0;
}