戳 这里(加了密码)。虽然写的可能还算清楚,但还是不公开了吧 QwQ。
真的想看的 私信可能会考虑给密码 qwq。就放个板子:
//LOJ 6053 简单的函数 f(p^c)=p xor c #include<bits/stdc++.h> #define int long long using namespace std; const int N=1e6+5,mod=1e9+7; int n,s,tot,val[N],id1[N],id2[N],x,cnt,p[N],sum[N],g[N],h[N],inv2=500000004; bool vis[N]; int id(int x){ return x<=s?id1[x]:id2[n/x]; } int S(int x,int y){ if(x<=1||p[y]>x) return 0; int ans=((g[id(x)]-h[id(x)]-(sum[y-1]-(y-1)))%mod+mod)%mod; if(y==1) ans+=2; for(int i=y;i<=cnt&&p[i]*p[i]<=x;i++){ int p1=p[i],p2=p[i]*p[i]; for(int e=1;p2<=x;e++,p1=p2,p2*=p[i]) ans=(ans+((p[i]^e)*S(x/p1,i+1)%mod+(p[i]^(e+1))%mod)%mod)%mod; } return ans; } signed main(){ scanf("%lld",&n),s=sqrt(n); vis[0]=vis[1]=1; for(int i=2;i<=s;i++){ if(!vis[i]) p[++cnt]=i,sum[cnt]=(sum[cnt-1]+i)%mod; for(int j=1;j<=cnt&&i*p[j]<=s;j++){ vis[i*p[j]]=1; if(i%p[j]==0) break; } } for(int l=1,r=0;l<=n;l=r+1){ r=n/(n/l),x=n/l,val[++tot]=x; if(x<=s) id1[x]=tot; else id2[n/x]=tot; x%=mod,g[tot]=(2+x)*(x-1)%mod*inv2%mod,h[tot]=(x-1)%mod; } for(int j=1;j<=cnt;j++) for(int i=1;i<=tot&&p[j]*p[j]<=val[i];i++){ g[i]=(g[i]-p[j]*(g[id(val[i]/p[j])]-sum[j-1])%mod+mod)%mod; h[i]=(h[i]-(h[id(val[i]/p[j])]-(j-1))%mod+mod)%mod; } printf("%lld ",S(n,1)+1); return 0; }