[集训队作业2018]uoj 448 人类的本质 - 线性筛 - min25筛

题目大意:求 i = 1 n x 1 = 1 i x 2 = 1 i x d = 1 i l c m j = 1 d [ gcd ( x j , i ) ] \sum_{i=1}^n\sum_{x_1=1}^i\sum_{x_2=1}^i\cdots\sum_{x_d=1}^i\mathrm{lcm}_{j=1}^d[\gcd(x_j,i)] n d 1 0 9 nd\le10^9
题解:结论是当i固定的时候答案 f ( i ) f(i) 是个积性函数,然后推啊推啊的就能推出式子,n比较小的时候跑线性筛(虽然我最后写了log)否则d表较小跑min_25筛。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define mod 1000000007
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
	int x,ch;while((ch=gc)<'0'||ch>'9');
	x=ch^'0';while((ch=gc)>='0'&&ch<='9')
		x=(x<<1)+(x<<3)+(ch^'0');return x;
}
inline int fast_pow(int x,int k,int ans=1) { for(;k;k>>=1,x=(lint)x*x%mod) (k&1)?ans=(lint)ans*x%mod:0;return ans; }
namespace SOLVE1_space{
	const int N=10000010;
	int np[N],p[N],q[N],f[N];
	inline int solve(int n,int d)
	{
		int ans=1;
		for(int i=2,c=0;i<=n;i++)
		{
			if(!np[i])
			{
				int t=i,v=fast_pow(i,d),w=(lint)v*i%mod,wi=w,pi=fast_pow(i,mod-2);
				p[++c]=i,f[i]=w-fast_pow(i-1,d+1),(f[i]<0?f[i]+=mod:0),q[i]=1;
				while(t<=n/i)
					t*=i,w=(lint)w*wi%mod,
					f[t]=((lint)v*f[t/i]+(1ll-pi)*(w-(lint)t*fast_pow(t-1,d)%mod))%mod,
					(f[t]<0?f[t]+=mod:0);
			}
			ans+=f[i],(ans>=mod?ans-=mod:0);
			for(int j=1;j<=c&&p[j]<=n/i;j++)
			{
				int x=p[j]*i;np[x]=1;
				if(i%p[j]==0)
				{
					q[x]=q[i];if(q[x]==1) continue;
					f[x]=(lint)f[x/q[x]]*f[q[x]]%mod;break;
				}
				else q[x]=i,f[x]=(lint)f[i]*f[p[j]]%mod;
			}
		}
		return !printf("%d\n",ans);
	}
}
inline int sol(int x,int s) { return (s&1)?(x?mod-x:0):x; }
namespace SOLVE2_space{
	const int SN=32000,D=110;
	int n,d,sn,pc,fac[D],facinv[D],np[SN],p[SN],mi[SN][D],pinv[SN];
	inline int prelude_fac(int n)
	{
		rep(i,fac[0]=1,n) fac[i]=(lint)fac[i-1]*i%mod;
		facinv[n]=fast_pow(fac[n],mod-2);
		for(int i=n-1;i>=0;i--) facinv[i]=(i+1ll)*facinv[i+1]%mod;
		return 0;
	}
	inline int C(int n,int m) { return (lint)fac[n]*facinv[m]%mod*facinv[n-m]%mod; }
	inline int prelude(int n)
	{
		pc=0;
		rep(i,2,n) if(!np[i])
		{
			p[++pc]=i,mi[i][0]=1,pinv[i]=fast_pow(i,mod-2);
			rep(j,1,d) mi[i][j]=(lint)mi[i][j-1]*i%mod;
			rep(j,i,n/i) np[i*j]=1;
		}
		return p[++pc]=n+1;
	}
	struct POLYVAL{
		int n,y[D],v[D],pre[D],suf[D];
		inline int init(int _k)
		{
			n=_k+2;
			rep(i,1,n) y[i]=y[i-1]+fast_pow(i,_k),(y[i]>=mod?y[i]-=mod:0);
			rep(i,1,n) v[i]=sol((lint)y[i]*facinv[i-1]%mod*facinv[n-i]%mod,n-i);
			return 0;
		}
		inline int operator()(int x)
		{
			if(x<=n) return y[x];pre[0]=suf[n+1]=1;int ans=0;
			for(int i=1;i<=n;i++) pre[i]=(lint)pre[i-1]*(x-i)%mod;
			for(int i=n;i>=1;i--) suf[i]=(lint)suf[i+1]*(x-i)%mod;
			rep(i,1,n) ans=(ans+(lint)v[i]*pre[i-1]%mod*suf[i+1])%mod;
			return ans;
		}
	}poly[D];int A[D][SN],B[D][SN],AS[SN],BS[SN];
	inline int Mysqrt(int n)
	{
		int x=(int)sqrt(n);while((lint)x*x<n) x++;
		while((lint)x*x>n) x--;return x;
	}
	inline int S(int x,int y)
	{
		if(x<p[y]) return 0;
		int res=(x<=sn?AS[x]:BS[n/x])-AS[p[y]-1];
		if(res<0) res+=mod;
		rep(z,y,pc&&p[z]<=x/p[z])
		{
			int nxt,pd=mi[p[z]][d],pi=pinv[p[z]],w=(lint)pd*p[z]%mod;
			int wi=w,vn,now=w-fast_pow(p[z]-1,d+1);(now<0?now+=mod:0);
			for(int v=p[z],e=1;v<=x/p[z];v*=p[z],e++,now=nxt)
				w=(lint)w*wi%mod,vn=v*p[z],
				nxt=((lint)pd*now+(1ll-pi)*(w-(lint)vn*fast_pow(vn-1,d)%mod))%mod,
				(nxt<0?nxt+=mod:0),res=(res+(lint)S(x/v,z+1)*now+nxt)%mod;
		}
		return res;
	}
	inline int solve(int __n,int __d)
	{
		n=__n,d=__d,prelude(sn=Mysqrt(n)),prelude_fac(d+5);
		rep(i,0,d) poly[i].init(i);
		rep(i,0,d) rep(j,1,sn) A[i][j]=poly[i](j),B[i][j]=poly[i](n/j);
		rep(p,2,sn) if(!np[p])
		{
			int r=p*p,ed1=sn/p,ed2=min(n/r,sn);
			rep(i,0,d)
			{
				int v=mi[p][i],*a=A[i],*b=B[i];
				rep(j,1,ed1) b[j]=(b[j]-(lint)v*(b[j*p]-a[p-1]))%mod,(b[j]<0?b[j]+=mod:0);
				rep(j,ed1+1,ed2) b[j]=(b[j]-(lint)v*(a[n/j/p]-a[p-1]))%mod,(b[j]<0?b[j]+=mod:0);
				for(int j=sn;j>=r;j--) a[j]=(a[j]-(lint)v*(a[j/p]-a[p-1]))%mod,(a[j]<0?a[j]+=mod:0);
			}
		}
		rep(j,1,sn) rep(i,0,d)
			AS[j]=(AS[j]+(lint)sol(C(d+1,i),d+i)*A[i][j])%mod,
			BS[j]=(BS[j]+(lint)sol(C(d+1,i),d+i)*B[i][j])%mod;
		int ans=S(n,1)+1;(ans>=mod?ans-=mod:0);return !printf("%d\n",ans);
	}
}
int main()
{
	int n=inn(),d=inn();
	if(n<=1e7) SOLVE1_space::solve(n,d);
	else SOLVE2_space::solve(n,d);return 0;
}

猜你喜欢

转载自blog.csdn.net/Mys_C_K/article/details/88165354