Description
Given a function f(x) that satisfies:
f(1)=1,
f(p^c)=p xor c, p is prime
f(ab)=f(a)*f(b),(a,b )=1
to find
n<=1e10
Solution
min_25 sieve
example problem, you can look at the blog of the god zzq.
We only need to know the sum of f(x) of all prime numbers. Obviously, the exponent is 1, so we can directly use the sum of prime numbers - the number of prime numbers.
Note that 2 is the only even prime number, just judge it at random.
Code
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int N=2e5+5,Mo=1e9+7;
int pwr(int x,int y) {
int z=1;
for(;y;y>>=1,x=(ll)x*x%Mo)
if (y&1) z=(ll)z*x%Mo;
return z;
}
int p[N],g[N],h[N],s[N],id1[N],id2[N],m,inv2,tot,cnt;
bool bz[N];
ll n,w[N];
void get_prime(int n) {
fo(i,2,n) {
if (!bz[i]) p[++tot]=i;
fo(j,1,tot) {
int k=i*p[j];if (k>n) break;
bz[k]=1;if (!(i%p[j])) break;
}
}
}
int ID(ll x) {return x<=m?id1[x]:id2[n/x];}
int F(ll x,int j) {
if (x<=1||p[j]>x) return 0;
int k=ID(x),ans=(g[k]-s[j-1]-(h[k]-(j-1)))%Mo;
if (j==1) ans+=2;
fo(i,j,tot) {
if ((ll)p[i]*p[i]>x) break;
ll t1=p[i],t2=(ll)p[i]*p[i];
for(int e=1;t2<=x;t1=t2,t2=t1*p[i],e++)
(ans+=(ll)F(x/t1,i+1)*(p[i]^e)%Mo+(p[i]^(e+1)))%=Mo;
}
return ans;
}
int main() {
scanf("%lld",&n);
m=sqrt(n);get_prime(m);
inv2=pwr(2,Mo-2);
for(ll l=1,r=0;l<=n;l=r+1) {
r=n/(n/l);
w[++cnt]=n/l;
int res=w[cnt]%Mo;
g[cnt]=(ll)res*(res+1)%Mo*inv2%Mo;g[cnt]--;
h[cnt]=(w[cnt]-1)%Mo;
if (w[cnt]<=m) id1[w[cnt]]=cnt;
else id2[n/w[cnt]]=cnt;
}
fo(i,1,tot) s[i]=(s[i-1]+p[i])%Mo;
fo(j,1,tot)
fo(i,1,cnt) {
if ((ll)p[j]*p[j]>w[i]) break;
int k=ID(w[i]/p[j]);
(g[i]-=(ll)p[j]*(g[k]-s[j-1])%Mo)%=Mo;(g[i]+=Mo)%=Mo;
(h[i]-=h[k]-(j-1))%=Mo;(h[i]+=Mo)%=Mo;
}
printf("%d\n",F(n,1)+1);
return 0;
}