[51nod1239]欧拉函数之和

来源:互联网 发布:数据库系统由什么组成 编辑:程序博客网 时间:2024/05/24 07:11

Description

i=1nφ(i)

n<=10^10

Solution

这道题和莫比乌斯函数一行,都可以通过神奇的推导的出结论。
我们设

ϕ(n)=i=1nφ(i)

众所周知,
d|nφ(d)=n

那么,
φ(n)=nd|n,d<nφ(d)

于是
ϕ(n)=i=1n(id|i,d<iφ(d))

ϕ(n)=n(n+1)2i=2nd|i,d<iφ(d)

ϕ(n)=n(n+1)2id=2nd=1nidφ(d)

ϕ(n)=n(n+1)2i=2nd=1niφ(d)

ϕ(n)=n(n+1)2i=2nϕ(ni)

于是和那道题一样做就好了。

还有一种做法。
这个问题的本质就是1~n中两两互质的数的对数。
那么我们可以用反演搞出来一个式子

Ans=i=1nμ(i)ni2

然后就分块搞就行了。
不过还是需要莫比乌斯函数前缀和。
参照51nod1244

Code

#include<cstdio>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define rep(i,a) for(int i=last[a];i;i=next[i])#define N 5000000using namespace std;typedef long long ll;const int Mo=1000000007;const int mo=2333333;const int ni=500000004;int phi[N+5],p[N+5],l;int last[mo],next[mo];bool bz[N+5];ll n,t[mo],v[mo];void add(int x,ll y,ll z) {    t[++l]=y;v[l]=z;next[l]=last[x];last[x]=l;}ll calc(ll x) {    if (x<=N) return phi[x];int k=x%mo;ll ans=0,z=x%Mo;    rep(i,k) if (t[i]==x) return v[i];    for(ll l=2,r;l<=x;l=r+1) r=x/(x/l),(ans+=(r-l+1)%Mo*calc(x/l)%Mo)%=Mo;    ans=(z*(z+1)%Mo*ni%Mo-ans+Mo)%Mo;    add(k,x,ans);    return ans;}int main() {    fo(i,2,N) {        if (!bz[i]) p[++p[0]]=i,phi[i]=i-1;        fo(j,1,p[0]) {            int k=i*p[j];if (k>N) break;            bz[k]=1;if (!(i%p[j])) {phi[k]=phi[i]*p[j];break;}            phi[k]=phi[i]*(p[j]-1);        }    }    phi[1]=1;fo(i,1,N) (phi[i]+=phi[i-1])%=Mo;    scanf("%lld",&n);printf("%lld",calc(n));}
0 0