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;
}