对于一个质数
p
p
p,除非它等于2,否则
p
x
o
r
1
=
p
−
1
p xor 1=p-1
pxor1=p−1
所以算一下
f
=
1
f=1
f=1和
s
=
p
s=p
s=p,相减即可
然后就变成min_25模板了?
Code:
#include<bits/stdc++.h>
#define ll long long
#define mod 1000000007
#define inv2 500000004
using namespace std;
inline ll read(){
ll res=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
return res*f;
}
inline int add(int x,int y){x+=y;if(x>=mod) x-=mod;return x;}
inline int dec(int x,int y){x-=y;if(x<0) x+=mod;return x;}
inline int mul(int x,int y){return 1ll*x*y%mod;}
inline void inc(int &x,int y){x+=y;if(x>=mod) x-=mod;}
inline void Dec(int &x,int y){x-=y;if(x<0) x+=mod;}
inline void Mul(int &x,int y){x=1ll*x*y%mod;}
inline int ksm(int a,int b){int res=1;for(;b;b>>=1,a=mul(a,a)) if(b&1) res=mul(res,a);return res;}
inline int sum(ll x){return mul(x%mod,mul((x+1)%mod,inv2));}
const int N=1e6+5;
int f1[N],f2[N],s1[N],s2[N],pri[N];
int tot=0;
inline void init(ll n){
if(n<=1) return;
int k=sqrt(n);
for(int i=1;i<=k;i++) f1[i]=i-1,f2[i]=(n/i-1)%mod,s1[i]=dec(sum(i),1),s2[i]=dec(sum(n/i),1);
for(int i=2;i<=k;i++){
if(f1[i]==f1[i-1]) continue;
pri[++tot]=i;
for(int j=1;j<=k/i;j++) Dec(f2[j],dec(f2[j*i],f1[i-1])),Dec(s2[j],mul(i,dec(s2[j*i],s1[i-1])));
for(int j=k/i+1;1ll*j*i*i<=n && j<=k;j++) Dec(f2[j],dec(f1[n/j/i],f1[i-1])),Dec(s2[j],mul(i,dec(s1[n/j/i],s1[i-1])));
for(int j=k;j>=1ll*i*i;j--) Dec(f1[j],dec(f1[j/i],f1[i-1])),Dec(s1[j],mul(i,dec(s1[j/i],s1[i-1])));
}
for(int i=1;i<=k;i++){
Dec(s1[i],f1[i]);inc(s1[i],mul(2,i>=2));
Dec(s2[i],f2[i]);inc(s2[i],mul(2,(n/i)>=2ll));
}
}
ll n;
int ans=1;
void calc(int cnt,int coef,int lim,ll res){
int g=(res<=lim?s1[res]:s2[n/res]);
inc(ans,mul(coef,dec(g,s1[pri[cnt-1]])));
for(int i=cnt;i<=tot;i++){
if(1ll*pri[i]*pri[i]>res) return;
for(ll now=pri[i],k=1;now<=res;k++){
if(now*pri[i]<=res) calc(i+1,mul(coef,pri[i]^k),lim,res/now);
if(k>=2) inc(ans,mul(coef,pri[i]^k));
now=now*pri[i];
}
}
}
int main(){
n=read();
init(n);
calc(1,1,sqrt(n),n);
cout<<ans<<"\n";
return 0;
}