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; }