/* 如果早点学习了欧拉函数,这个题目也许就不会做不出来了 下面我们求出小于N且与N互质的正整数之和, 设为S. 不妨设这些数为a[1], a[2], ..., a[ phi(N) ], 其中phi(N)是N的欧拉函数值.对1 <= i <= phi(N), 由gcd(N, a[i]) = 1可知gcd(N, N - a[i]) = 1. 这里可以采用反证: (这里我觉得用中国的剩余定理就可以证明的) 设gcd(N, N - a[i]) = k > 1, 则k|N, k|(N - a[i]) -> k|a[i] -> k|gcd(N, a[i]), 而gcd(N, a[i]) = 1, 矛盾. 这样, N - a[1], N - a[2], ..., N - a[ phi(N) ]也对应着原数列, 则有: S = a[1] + a[2] + ... + a[ phi(N) ] S = (N - a[1]) + (N - a[2]) + ... + (N - a[ phi[N] ]) 两式相加得: S = N * phi(N) / 2, 所求结果即为( N * (N - 1) / 2 - S) Mod 1000000007. */ #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int mod = 1000000007; bool hash[100005]; int main() { int n; memset(hash, false, sizeof(hash)); for(int i = 2; i < 10001; i++) if(!hash[i]) for(int j = i + i; j < 100001; j += i) hash[j] = true; while( scanf("%d", &n) != EOF && n) { if(n <= 3) { puts("0"); continue; } long long sum = 0; long long s = n; int num = n; for(int i = 2; i < 50000; i++) { if(hash[i]) continue; if(num == 1 || i >= n) break; bool flag = false; while(true) { if(num % i != 0) break; num /= i; flag = true; } if(flag) s = s *(i - 1)/i; } if(num > 1)// 这里错了,一直改不出来,看来第一次写欧拉函数不顺利的,有比50000 大的素数因子的和 s = s / num * (num - 1); sum = n * (n - 1 - s) / 2; printf("%lld/n", sum % mod); } return 0; }