Description
某一天,你发现了一个神奇的函数
f(x)
f
(
x
)
,它满足很多神奇的性质:
1.
f(1)=1
f
(
1
)
=
1
2.
f(pc)=p⊕c
f
(
p
c
)
=
p
⊕
c
(⊕表示异或)
3.
f(ab)=f(a)f(b)
f
(
a
b
)
=
f
(
a
)
f
(
b
)
(
a
a
与互质)
你看到这个函数之后十分高兴,于是就想要求出 ∑ni=1f(i) ∑ i = 1 n f ( i )
由于这个数比较大,你只需要输出 ∑ni=1f(i)mod(109+7) ∑ i = 1 n f ( i ) mod ( 10 9 + 7 )
Solution
Min_25版子题
【数论】Min_25筛
Code
代码中包含递归和非递归版本,注释中的均为递归版本,非注释中的是非递归版本
全部改非递归的后更慢了???懵
#include <cstdio>
#include <algorithm>
#include <cmath>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
#define min(q,w) ((q)>(w)?(w):(q))
#define max(q,w) ((q)<(w)?(w):(q))
#define GALL(q) ((1LL+(q))*(LL)(q)/2%mo)
using namespace std;
typedef long long LL;
const int N=200500,mo=1000000007;
int read(int &n)
{
char ch=' ';int q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-')w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
LL n,ans;
int M;
bool prz[N];
int pr[N/3];
int prs[N],prc[N],ps[N];
void Pre(int n)
{
fo(i,2,n)
{
if(!prz[i])pr[++pr[0]]=i,prs[i]=i,prc[i]=1,ps[pr[0]]=(ps[pr[0]-1]+i)%mo;
((prs[i]+=prs[i-1])>=mo?prs[i]-=mo:0);
prc[i]+=prc[i-1];
fo(j,1,pr[0])
{
int t=i*pr[j];
if(t>n)break;
prz[t]=1;
if(i%pr[j]==0)break;
}
}
}
/*LL Gf(LL n,int m)
{
if(!m)return GALL(n)-1;
if(n<=N&&n<(LL)pr[m+1]*pr[m+1])return f[n];
for(;n<(LL)pr[m+1]*pr[m+1];--m);
LL ans=GALL(n)-1;
for(;m;--m)ans=(ans-(Gf(n/pr[m],m-1)-f[pr[m]-1])*pr[m])%mo;
return ans;
}*/
LL d[N];
int dz1[N],dz[N];
int f[N],f0[N];
LL Gf(LL n)
{
for(LL i=1,nx;i<=n;i=nx+1)
{
nx=n/(n/i);
LL t=d[++d[0]]=n/i;
f0[d[0]]=(t-1)%mo;
f[d[0]]=(((t&1)?((t+1LL)/2%mo*(t%mo)):(t/2%mo*(t%mo+1LL)))-1LL)%mo;
if(t<=N)dz[t]=d[0];
else dz1[n/t]=d[0];
}
fo(j,1,pr[0]-1)
{
LL pf=(LL)pr[j]*pr[j];
for(int i=1;i<=d[0]&&pf<=d[i];++i)
{
int q=(d[i]/pr[j]<=N)?dz[d[i]/pr[j]]:dz1[n/(d[i]/pr[j])];
f[i]=(f[i]-((LL)f[q]-prs[pr[j]-1])%mo*(LL)pr[j])%mo;
f0[i]=(f0[i]-((LL)f0[q]-prc[pr[j]-1]))%mo;
}
}
return f[1]-f0[1];
}
/*LL Gg(LL n,int m)
{
if(n<2||n<pr[m])return 0;
LL ans=((n<=N)?(f[dz[n]]-f0[dz[n]]):(f[dz1[(::n)/n]]-f0[dz1[(::n)/n]]))%mo;
ans=(ans-(LL)ps[m-1]+(LL)m-1LL)%mo;
for(;(LL)pr[m]*pr[m]<=n;++m)
{
LL p=pr[m],p1=(LL)pr[m]*pr[m];
for(LL k=1;p1<=n;p=p1,p1*=(LL)pr[m],++k)
ans=(ans+Gg(n/p,m+1)*(LL)(pr[m]^k)%mo+(LL)(pr[m]^(k+1)))%mo;
}
return ans;
}*/
int g[N];
LL Gg(LL n)
{
fod(j,pr[0]-1,1)
{
for(int i=1;(LL)pr[j]*pr[j]<=d[i];++i)
{
LL p=pr[j],p1=(LL)pr[j]*pr[j];
for(int k=1;p1<=d[i];p=p1,p1*=(LL)pr[j],++k)
{
LL w=d[i]/p;
int q=(w<=N)?dz[w]:dz1[n/(w)];
LL t=g[q];
if(w>=pr[j+1])t=(t+(f[q]-f0[q])-ps[j]+(LL)j)%mo;
g[i]=(g[i]+t*(pr[j]^k)+(pr[j]^(k+1)))%mo;
}
}
}
return (g[1]+(f[1]-f0[1]))%mo;
}
int main()
{
int q,w;
scanf("%lld",&n);
if(n==1)return printf("1\n"),0;
M=2LL*sqrt(n);
Pre(M);
Gf(n);
printf("%lld\n",(Gg(n)+3LL+mo)%mo);
return 0;
}