求小于n的与n不互质的数之和
先证下gcd(n,i) = gcd(n,n-i)
e=gcd(n,i) f=gcd(n,n-i)
e|n&&e|i-> e|n-i e<=f
f|n&&f|n-i f|i e>=f 所以e=f
即若gcd(n,i)=1 gcd(n,n-i)=1 与n互质的数之和为n的成对存在
(n,n/2)=n/2 不互质 不会重复计算
所以与n互质的数之和为n*(phi[n]/2)
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll Euler(ll n)
{
//Euler(n)=n*(1-1/p1)*(1-1/p2)...(1-1/pn)
//通分=n*((p1-1)/p1)*((p2-1)/p2)...((pn-1)/pn)
ll m=sqrt(n+0.5);
ll ans=n;
for(int i=2;i<=m;i++)// n的素因子i
{
if(n%i==0)
{
ans=ans/i*(i-1);
}
while(n%i==0)//不在考虑素因子i
n/=i;
}
if(n>1)//素因子大于m
ans=ans/n*(n-1);
return ans;
}
int main()
{
ll n;
while(cin>>n&&n)
{
ll ans=Euler(n);
// 求小于n的与n不互质的数之和
//先证下gcd(n,i) = gcd(n,n-i)
// e=gcd(n,i) f=gcd(n,n-i)
//e|n&&e|i-> e|n-i e<=f
//f|n&&f|n-i f|i e>=f 所以e=f
//即若gcd(n,i)=1 gcd(n,n-i)=1 与n互质的数为成对存在&&和为n
// (n,n/2)=n/2 不互质 不会重复计算
//所以与n互质的数之和为n*(phi[i]/2)
ll sum=((1+(n-1))*(n-1))/2;
ans=n*ans/2;
sum-=ans;
sum=sum%mod;
cout<<sum<<endl;
}
return 0;
}