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
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);
}
转载请注明原文地址: https://ju.6miu.com/read-7141.html