http://acmoj.shu.edu.cn/problem/419/
【思路】
打表找规律,发现g(n)=∑φ(i)*[n/i]=n(n+1)/2 (1<=i<=n)
证明:g(n)-g(n-1)= ∑ψ(x),1<=x<=n && x|n
而∑ψ(x)=n,1<=x<=n && x|n
【Accepted】
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<string> 5 #include<cstring> 6 using namespace std; 7 const int maxn=1e5+3; 8 typedef long long ll; 9 const ll mod=1e9+7; 10 ll n; 11 ll fpow(ll x,ll n) 12 { 13 ll res=1LL; 14 while(n) 15 { 16 if(n&1) 17 { 18 res=(res*x)%mod; 19 } 20 x=(x*x)%mod; 21 n>>=1; 22 } 23 return res; 24 } 25 ll eular(ll n) 26 { 27 ll ans=n; 28 for(int i=2;i*i<=n;i++) 29 { 30 if(n%i==0) 31 { 32 ans-=ans/i; 33 while(n%i==0) 34 { 35 n/=i; 36 } 37 } 38 } 39 if(n>1) 40 { 41 ans-=ans/n; 42 } 43 return ans; 44 } 45 int main() 46 { 47 int T; 48 scanf("%d",&T); 49 while(T--) 50 { 51 cin>>n; 52 ll x=n*(n+1)%mod*fpow(2LL,mod-2LL)%mod; 53 ll sum=0LL; 54 for(ll i=1;i<233;i++) 55 { 56 sum=(sum+eular(i)*(n/i)%mod)%mod; 57 } 58 for(int i=n;i>n-233;i--) 59 { 60 sum=(sum+eular(i)*(n/i)%mod)%mod; 61 } 62 ll res=(x-sum+mod)%mod; 63 cout<<res<<endl; 64 65 } 66 return 0; 67 }
【注意】
这道题还是wa了两回,因为以下两点一开始没有注意到:
1. 在取模运算下除法不能直接除,而是对应乘以它的逆元,所以计算n*(n+1)/2时,是乘以fpow(2,mod-2);
2. n*(n+1)*fpow(2,mod-2)%mod是不对的,会爆ll,在n*(n+1)之后就该mod
【收获】
打表找规律以及欧拉函数的常用性质