Description
对正整数n,欧拉函数是小于或等于n的数中与n互质的数的数目。此函数以其首名研究者欧拉命名,它又称为Euler’s totient function、φ函数、欧拉商数等。例如:φ(8) = 4(Phi(8) = 4),因为1,3,5,7均和8互质。
S(n) = Phi(1) + Phi(2) + …… Phi(n),给出n,求S(n),例如:n = 5,S(n) = 1 + 1 + 2 + 2 + 4 = 10,定义Phi(1) = 1。由于结果很大,输出Mod 1000000007的结果。
Solution
这道题本来是不会的,问了一下欧拉函数的性质,石化……
n=∑d|nϕ(d)
然后这道题就好解了。
f(n)=∑i=1nϕ(i)=∑i=1n∑d|iϕ(i)−∑i=1n∑d|i,d<iϕ(i)
好像一句废话……
f(n)=∑i=1n∑d|iϕ(i)−∑i=1n∑d|i,d<iϕ(i)=n∗(n+1)2−∑i=1n∑d|i,d<iϕ(i)
设T=id,因为要满足d|i,d<i,所以T>1且为整数
f(n)=n∗(n+1)2−∑T=2n∑d=1n/Tϕ(⌊nd⌋)=n∗(n+1)2−∑T=2nf(⌊nd⌋)
最后分块一下,用哈希表判重就好了。但是,这还是不行,我们还要预处理一下前10^6的答案,这样就解决了。
有另外一道题和这很像 51nod 1244 莫比乌斯函数之和
Code
#include<iostream>
#include<math.h>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#define ll long long
using namespace std;
const ll maxn=1e7+5,mo=1e9+7,mo2=5e8+4,maxn1=1e6+5;
int f[maxn],bz[maxn1+5],d[maxn1],p[maxn+5];
ll h[maxn],n,i,t,j,k,l,x,y,z,ans;
int hash(ll x){
ll t=x%maxn;
while (h[t]&& h[t]!=x) t=(t+1)%maxn;
return t;
}
int dg(ll n){
if (n<=maxn1) return p[n];
ll t,i=2,x=n%mo,k=x*(x+1)%mo*mo2%mo,l=hash(n);
if (h[l]) return f[l];
while (i<=n){
t=n/(n/i);
k=k-(t-i+1)*dg(n/i)%mo;i=t+1;
}
k=(k%mo+mo)%mo;
h[l]=n;f[l]=k;return k;
}
int main(){
//freopen("data.in","r",stdin);
p[1]=1;
for (i=2;i<=maxn1;i++){
if (!bz[i]) d[++d[0]]=i,p[i]=i-1;
for (j=1;j<=d[0];j++){
if (i*d[j]>maxn1) break;
bz[i*d[j]]=1;
if (i%d[j]==0){
p[i*d[j]]=p[i]*d[j];break;
}p[i*d[j]]=p[i]*p[d[j]];
}
}
for (i=1;i<=maxn1;i++)
p[i]=(p[i]+p[i-1])%mo;
scanf("%lld",&n);
ans=dg(n);
printf("%lld\n",ans);
}