Min_25筛模板

#include<bits/stdc++.h>
#define IL inline
#define LL long long
using namespace std;
const LL N=1e10+3,M=2e5+3;
const int p=1e9+7;
LL n;int a[M];
IL int mod(int x){return x>=p?x-p:x;}
IL int ksm(int a,int b){
	int c=1;
	while(b){
		if(b&1) c=1ll*c*a%p;
		b>>=1,a=1ll*a*a%p;
	}
	return c;
}
struct Min_25{
	LL n,nn[M];
	int m,k,ans,cp,cn,f[M],vis[M],inv[M],id1[M],id2[M],pri[M],a[M],G[M],SG[M];
	vector<int>g[M],sg[M];
	IL int calc(LL n,int k){
		n%=p;
		if(k==0) return 1;
		if(k==1) return n;
		if(k==2) return 1ll*n*n%p;
	}
	IL int calcsg(LL n,int k){
		n%=p;
		if(k==0) return mod(n+p-1);
		if(k==1) return mod((n*(n+1)>>1)%p-1+p);
		if(k==2) return mod((n*(n+1)>>1)%p*mod(2*n+1)%p*inv[3]%p-1+p);
	}
	IL int js(LL pp,LL k,LL pk){return pk*(pk-1)%p;}
	int S(LL x,int y){
		if(pri[y]>=x) return 0;
		int id=x<=m?id1[x]:id2[n/x];
		int ans=mod(G[id]-SG[y]+p);
		for(int i=y+1;i<=cp&&1ll*pri[i]*pri[i]<=x;++i){
			LL pp=pri[i],pk=pp;
			for(int j=1;pk<=x;pk*=pp,++j){
				LL z=pk%p;
				ans=mod(ans+1ll*js(pp,j,z)*mod(S(x/pk,i)+(j>1))%p);
			}
		}
		return ans;
	}
	void solve(LL n,int k,int *a){
		this->n=n,this->k=k;
		for(int i=0;i<=k;++i) this->a[i]=a[i],g[i].resize(M,0),sg[i].resize(M,0);
		for(int i=2;i<=10;++i) inv[i]=ksm(i,p-2);
		m=sqrt(n)+1;
		for(int i=2;i<=m;++i){
			if(!vis[i]){
			  pri[++cp]=i,vis[i]=i;
			  for(int j=0;j<=k;++j) sg[j][cp]=mod(sg[j][cp-1]+calc(i,j));
			}
			for(int j=1;j<=cp&&pri[j]<=vis[i]&&pri[j]*i<=m;++j) vis[pri[j]*i]=pri[j];
		}
		for(LL i=1,j,d;i<=n;i=j+1){
			d=n/i,j=n/d,nn[++cn]=d;
			if(d<=m) id1[d]=cn;else id2[j]=cn;
			for(int l=0;l<=k;++l) g[l][cn]=calcsg(d,l);
		}
		for(int i=1;i<=cp;++i)
		  for(int j=1;j<=cn&&1ll*pri[i]*pri[i]<=nn[j];++j){
		  	int id=nn[j]/pri[i]<=m?id1[nn[j]/pri[i]]:id2[n/(nn[j]/pri[i])];
		  	for(int l=0;l<=k;++l) g[l][j]=mod(g[l][j]+1ll*calc(pri[i],l)*mod(sg[l][i-1]-g[l][id]+p)%p);
		  }
		for(int i=0;i<=k;++i)
		  for(int j=1;j<=cn;++j)
		    G[j]=mod(G[j]+1ll*a[i]*g[i][j]%p);
		for(int j=1;j<=cp;++j){
			SG[j]=SG[j-1];
			for(int i=0;i<=k;++i)
		    SG[j]=mod(SG[j]+1ll*a[i]*calc(pri[j],i)%p);
		}
		ans=mod(S(n,0)+1);printf("%d\n",ans);
	}
}min_25;
int main()
{
	scanf("%lld",&n),a[1]=p-1,a[2]=1;min_25.solve(n,2,a);
	return 0;
}
posted @ 2022-08-10 22:30  (o-ωq)).oO  阅读(34)  评论(0编辑  收藏  举报