某一天,你發現了一個神奇的函數\(f(x)\),它知足不少神奇的性質:ios
\(f(1)=1\)。git
\(f(p^c)=p \oplus c\)(\(p\) 爲質數,\(\oplus\)表示異或)。函數
\(f(ab)=f(a)\cdot f(b)\)(\(a\) 與 \(b\) 互質)。spa
你看到這個函數以後十分高興,因而就想要求出 \(\sum\limits_{i=1}^n f(i)\)。code
因爲這個數比較大,你只須要輸出 \(\sum\limits_{i=1}^n f(i) \bmod (10^9+7)\)。ip
一行一個整數 \(n\)。get
一行一個整數 \(\sum\limits_{i=1}^n f(i) \bmod 1000000007\)。string
6it
16io
233333
179004642
9876543210
895670833
對於\(30\%\)的數據,\(n \leq 100\)。
對於\(60\%\)的數據,\(n \leq 10^6\)。
對於\(100\%\)的數據,\(1 \leq n \leq 10^{10}\)。
要求\(f(p^c)=p\oplus c\),
對除\(2\)之外的質數\(p\)而言,等價於求\(f(p)=p-1\)。
咱們能夠用該函數來求\(g\),
然而,因爲該函數並非一個徹底積性函數,
咱們須要把它拆成兩個部分,分爲\(f_1(p)=p,f_2(p)=1\),
並預處理出對應的\(g(n,j),h(n,j)\)。
此時,\(S(n,j)\)的初值爲
\[ g(n,|P|)-h(n,|P|)-\sum_{i=1}^{j-1}f(p) \]
須要注意的是,若\(j=1\),\(f(2)\)會被計算在答案之中,
可是在上面預處理的時候咱們算的是\(f(2)=1\),需額外加\(2\)。
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<iomanip> #include<cstdlib> #define MAXN 0x7fffffff typedef long long LL; const int N=250005,mod=1e9+7; const int inv2=5e8+4; using namespace std; inline LL Getint(){register LL x=0,f=1;register char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}return x*f;} bool vis[N]; int prime[N],tot; LL n,sqr,w[N],h[N],g[N],sp[N]; int id1[N],id2[N],m; void Pre(int n){ vis[1]=1; for(int i=2;i<=n;i++){ if(!vis[i])prime[++tot]=i,sp[tot]=sp[tot-1]+i; for(int j=1;j<=tot&&1ll*i*prime[j]<=n;j++){ vis[i*prime[j]]=1; if(i%prime[j]==0)break; } } } int S(LL x,int y){ if(x<=1||prime[y]>x)return 0; int k=(x<=sqr)?id1[x]:id2[n/x],ret=(g[k]-sp[y-1]-h[k]+y-1)%mod; if(y==1)ret+=2; for(int i=y;i<=tot&&1ll*prime[i]*prime[i]<=x;i++){ LL t1=prime[i],t2=1ll*prime[i]*prime[i]; for(int e=1;t2<=x;++e,t1=t2,t2*=prime[i]) (ret+=1ll*S(x/t1,i+1)*(prime[i]^e)%mod+((prime[i]^(e+1))%mod))%=mod; } return ret; } int main(){ n=Getint(),sqr=sqrt(n); Pre(sqr); for(LL i=1,j;i<=n;i=j+1){ j=n/(n/i),w[++m]=n/i; g[m]=(w[m]%mod)*((w[m]+1)%mod)%mod*inv2%mod-1; h[m]=(w[m]-1)%mod; if(w[m]<=sqr)id1[w[m]]=m;else id2[j]=m; } for(int j=1;j<=tot;j++){ for(int i=1;i<=m&&1ll*prime[j]*prime[j]<=w[i];i++){ int k=(w[i]/prime[j]<=sqr)?id1[w[i]/prime[j]]:id2[n/(w[i]/prime[j])]; (g[i]-=prime[j]*(g[k]-sp[j-1]))%=mod; (h[i]-=h[k]-j+1)%=mod; } } int ans=S(n,1)+1; cout<<(ans+mod)%mod; return 0; }