LOJ6053简单的函数(min_25筛)
LOJ6053简单的函数
https://loj.ac/p/6053
min_25筛模板题,但是要注意质数点有2比较特殊,需要在y==0的时候特判质数包含2的情况。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
inline LL read()
{
char x='\0';
LL fh=1,sum=0;
for(x=getchar();x<'0'||x>'9';x=getchar())if(x=='-')fh=-1;
for(;x>='0'&&x<='9';x=getchar())sum=sum*10+x-'0';
return fh*sum;
}
const LL N=1000009;
const LL mod=1e9+7;
LL n,sq;
LL pri[N],pcnt,sp[N];
bool vis[N];
inline void init(int mx)
{
vis[0]=vis[1]=true;
for(LL i=2;i<=mx;i++)
{
if(!vis[i])pri[++pcnt]=i,sp[pcnt]=(sp[pcnt-1]+i)%mod;
for(int j=1;j<=pcnt&&i*pri[j]<=mx;j++)
{
vis[i*pri[j]]=true;
if(i%pri[j]==0)break;
}
}
}
LL w[N],tot,ind1[N],ind2[N],g1[N],g0[N];
inline LL S(LL x,int y)
{
if(x<=1||pri[y]>=x)return 0;
LL k=(x<=sq)?ind1[x]:ind2[n/x];
LL ans=g1[k]-g0[k]-(sp[y]-y);
if(y==0)ans+=2;
for(int i=y+1;i<=pcnt&&pri[i]*pri[i]<=x;i++)
{
for(LL j=1,pe=pri[i];pe<=x;j++,pe*=pri[i])
{
ans=(ans+(pri[i]^j)*(S(x/pe,i)+(j!=1))%mod)%mod;
}
}
return ans;
}
int main()
{
n=read();
sq=sqrt(n);
init(sq);
for(LL lp=1,rp=0;lp<=n;lp=rp+1)
{
rp=n/(n/lp);
w[++tot]=n/lp;
if(w[tot]<=sq)ind1[w[tot]]=tot;
else ind2[n/w[tot]]=tot;
LL now=w[tot]%mod;
g1[tot]=(now*(now+1)/2%mod-1+mod)%mod;
g0[tot]=(now-1+mod)%mod;
}
// cout<<g1[1]<<endl;//
for(int i=1;i<=pcnt;i++)
{
for(int j=1;j<=tot&&pri[i]*pri[i]<=w[j];j++)
{
LL now=w[j]/pri[i];
LL k=(now<=sq)?ind1[now]:ind2[n/now];
g1[j]=(g1[j]-pri[i]*(g1[k]-sp[i-1])%mod+mod)%mod;
g0[j]=(g0[j]-(g0[k]-(i-1))+mod)%mod;
}
}
// cout<<g1[1]<<' '<<g0[1]<<endl;//
printf("%lld",(S(n,0)+1)%mod);
return 0;
}

浙公网安备 33010602011771号