【2020省选模拟】题解

T1:

显然莫反
枚举 g c d gcd gcd莫反得
a n s = ∑ d = 1 d ∑ p = 1 n d μ ( p ) f ( n p d ) ans=\sum_{d=1}d\sum_{p=1}^{\frac nd }\mu(p)f(\frac{n}{pd}) ans=d=1dp=1dnμ(p)f(pdn)
其中 f ( n ) = ∑ i = 1 n ∑ j = 1 i ∑ k = 1 i 1 = n ( n + 1 ) ( 2 n + 1 ) 6 f(n)=\sum_{i=1}^n\sum_{j=1}^i\sum_{k=1}^i1=\frac{n(n+1)(2n+1)}{6} f(n)=i=1nj=1ik=1i1=6n(n+1)(2n+1)
a n s = ∑ T = 1 n g ( T ) f ( n T ) ans=\sum_{T=1}^ng(T)f(\frac n T) ans=T=1ng(T)f(Tn)
其中 g ( n ) = ∑ d ∣ n d μ ( n d ) = I d ∗ μ = ϕ g(n)=\sum_{d|n}d\mu(\frac nd)=Id*\mu=\phi g(n)=dndμ(dn)=Idμ=ϕ
整除分块+杜教筛即可

#include
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair
#define ll long long
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
    static char ibuf[RLEN],*ib,*ob;
    (ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    return (ib==ob)?EOF:*ib++;
}
inline int read(){
    char ch=gc();
    int res=0;bool f=1;
    while(!isdigit(ch))f^=ch=='-',ch=gc();
    while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    return f?res:-res;
}
inline ll readll(){
    char ch=gc();
    ll res=0;bool f=1;
    while(!isdigit(ch))f^=ch=='-',ch=gc();
    while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    return f?res:-res;
}
inline int readstring(char *s){
	int top=0;char ch=gc();
	while(isspace(ch))ch=gc();
	while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
	return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<typename tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
int mod;
inline int add(int a,int b){return (a+b)>=mod?(a+b-mod):(a+b);}
inline int dec(int a,int b){return (a<b)?(a-b+mod):(a-b);}
inline int mul(int a,int b){static ll r;r=(ll)a*b;return (r>=mod)?(r%mod):r;}
inline void Add(int &a,int b){a=(a+b)>=mod?(a+b-mod):(a+b);}
inline void Dec(int &a,int b){a=(a<b)?(a-b+mod):(a-b);}
inline void Mul(int &a,int b){static ll r;r=(ll)a*b;a=(r>=mod)?(r%mod):r;}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
inline int Inv(int x){return ksm(x,mod-2);}
inline int fix(int x){return (x<0)?x+mod:x;}
int inv6,inv2;
inline int S3(int x){return mul(mul(x,x+1),mul(mul(2,x)+1,inv6));}
inline int S2(int x){return mul(x,mul(x+1,inv2));}
int n;
cs int N=1000006;
int pr[N],tot,mu[N],phi[N],s[N];
bool vis[N];
inline void init_sieve(cs int n=N-5){
	mu[1]=1,phi[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i])pr[++tot]=i,mu[i]=mod-1,phi[i]=i-1;
		for(int p,j=1;j<=tot&&i*pr[j]<=n;j++){
			p=i*pr[j];vis[p]=1;
			if(i%pr[j]==0){phi[p]=phi[i]*pr[j];break;}
			mu[p]=mod-mu[i],phi[p]=phi[i]*(pr[j]-1);
		}
	}
	for(int i=1;i<=n;i++)s[i]=add(s[i-1],phi[i]);
}
map<int,int>mp;
inline int S(int x){
	if(mp.count(x))return mp[x];
	if(x<=1e6)return s[x];
	int res=S2(x);
	for(int l=2,r;l<=x;l=r+1){
		r=x/(x/l);
		Dec(res,mul(r-l+1,S(x/l)));
	}
	return mp[x]=res;
}
int main(){
	freopen("yang.in","r",stdin);
	freopen("yang.out","w",stdout);
	n=read(),mod=read();
	inv6=Inv(6),inv2=Inv(2);
	init_sieve();
	int res=0;
	for(int l=1,pre=0,now=0,r;l<=n;l=r+1){
		r=n/(n/l);now=S(r);
		Add(res,mul(S3(n/l),dec(now,pre)));
		pre=now;
	}cout<<res<<'\n';
}

T2:

l d x ldx ldx日常教育我系列/kk

一个做法是考虑 f ( x ) = ∑ i = 1 x i k f(x)=\sum_{i=1}^xi^k f(x)=i=1xik是一个 k + 1 k+1 k+1次多项式
先求出这个多项式,可以插值
那么答案实际就是 ∑ i = 1 n ( n i ) Q i f ( i ) \sum_{i=1}^n{n\choose i}Q^if(i) i=1n(in)Qif(i)
下面用 k k k指代 f ( x ) f(x) f(x)的次数
考虑换一下变成对于每个 t = 0... k t=0...k t=0...k求出 ∑ i = 1 n ( n i ) Q i i t \sum_{i=1}^n{n\choose i}Q^ii^t i=1n(in)Qiit
变一下变成求 n ! Q n ∑ i = 0 n i t i ! Q i − n ( n − i ) ! n!Q^n\sum_{i=0}^n\frac{i^t}{i!}\frac{Q^{i-n}}{(n-i)!} n!Qni=0ni!it(ni)!Qin
f t ( x ) = ∑ i = 0 ∞ i t x i i ! f_t(x)=\sum_{i=0}^{\infty}\frac{i^tx^i}{i!} ft(x)=i=0i!itxi
那么后面就是 [ x n ] ( f t ( x ) e 1 Q x ) [x^n](f_t(x)e^{\frac 1 Qx}) [xn](ft(x)eQ1x)
又有 f t ( x ) = x f t − 1 ′ ( x ) , f 0 = e x f_t(x)=xf'_{t-1}(x),f_0=e^x ft(x)=xft1(x),f0=ex
若设 f t ( x ) = e x ∗ A t , 则 A t = x ( A t − 1 + A t − 1 ′ ) f_t(x)=e^x*A_t,则A_t=x(A_{t-1}+A_{t-1}') ft(x)=exAt,At=x(At1+At1)
可以只维护最后 i ∈ [ n − k + 1 , k ] , x i i\in[n-k+1,k],x^i i[nk+1,k],xi这些项即可
复杂度 O ( k 2 ) O(k^2) O(k2)


我的做法
直接将 ∑ i = 0 n ( n i ) Q i ∑ j = 0 i j k \sum_{i=0}^n{n\choose i}Q^i\sum_{j=0}^ij^k i=0n(in)Qij=0ijk后面 j k j^k jk斯特林展开

∑ i = 0 n ( n i ) Q i ∑ j = 0 i ∑ t = 0 k ( j t ) t ! S k , t = ∑ t = 0 k t ! S k , t ∑ i = 0 n ( n i ) Q i ∑ j = 0 i ( j t ) = ∑ t = 0 k t ! S k , t ∑ i = 0 n ( n i ) Q i ( i + 1 t + 1 ) = ∑ t = 0 k t ! S k , t ∑ i = 0 n n ! ( i + 1 ) ! i ! ( n − i ) ! ( t + 1 ) ! ( i − t ) ! Q i = ∑ t = 0 k S k , t t + 1 Q t ∑ i = 0 n − t n ! ( i + t + 1 ) ( n − i − t ) ! i ! Q i = ∑ t = 0 k S k , t Q t n ! ( n − t ) ! ( t + 1 ) ∑ i = 0 n − t ( n − t i ) ( i + t + 1 ) Q i \sum_{i=0}^n{n\choose i}Q^i\sum_{j=0}^i\sum_{t=0}^k{j\choose t}t!S_{k,t}\\ =\sum_{t=0}^kt!S_{k,t}\sum_{i=0}^n{n\choose i}Q^i\sum_{j=0}^{i}{j\choose t}\\ =\sum_{t=0}^kt!S_{k,t}\sum_{i=0}^n{n\choose i}Q^i{i+1\choose t+1}\\ =\sum_{t=0}^kt!S_{k,t}\sum_{i=0}^n\frac{n!(i+1)!}{i!(n-i)!(t+1)!(i-t)!}Q^i\\ =\sum_{t=0}^k\frac{S_{k,t}}{t+1}Q^t\sum_{i=0}^{n-t}\frac{n!(i+t+1)}{(n-i-t)!i!}Q^i\\ =\sum_{t=0}^kS_{k,t}Q^t\frac{n!}{(n-t)!(t+1)}\sum_{i=0}^{n-t}{n-t\choose i}(i+t+1)Q^i i=0n(in)Qij=0it=0k(tj)t!Sk,t=t=0kt!Sk,ti=0n(in)Qij=0i(tj)=t=0kt!Sk,ti=0n(in)Qi(t+1i+1)=t=0kt!Sk,ti=0ni!(ni)!(t+1)!(it)!n!(i+1)!Qi=t=0kt+1Sk,tQti=0nt(nit)!i!n!(i+t+1)Qi=t=0kSk,tQt(nt)!(t+1)n!i=0nt(int)(i+t+1)Qi

然后推到这里的时候傻逼般的卡着了
然后被 l d x ldx ldx大力教育了一顿
对于后面 ∑ i = 0 n − t ( n − t i ) ( i + t + 1 ) Q i = ( t + 1 ) ∑ i = 0 n − t ( n − t i ) Q i + Q ( n − t ) ∑ i = 0 n − t − 1 Q i ( n − t − 1 i ) = ( t + 1 ) ( p + 1 ) n − t + Q ( n − t ) ( Q + 1 ) n − t − 1 \sum_{i=0}^{n-t}{n-t\choose i}(i+t+1)Q^i\\ =(t+1)\sum_{i=0}^{n-t}{n-t\choose i}Q^i+Q(n-t)\sum_{i=0}^{n-t-1}Q^i{n-t-1\choose i}\\ =(t+1)(p+1)^{n-t}+Q(n-t)(Q+1)^{n-t-1} i=0nt(int)(i+t+1)Qi=(t+1)i=0nt(int)Qi+Q(nt)i=0nt1Qi(int1)=(t+1)(p+1)nt+Q(nt)(Q+1)nt1

于是后面一整块可以 O ( k ) O(k) O(k)
瓶颈在于前面的斯特林数
复杂度 O ( k 2 / k l o g k ) O(k^2/klogk) O(k2/klogk)
于是可以出到 k = 1 e 6 k=1e6 k=1e6
我懒,只写了 O ( k 2 ) O(k^2) O(k2)
注意 k = 0 k=0 k=0 c o r n e r   c a s e corner\ case corner case

#include
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair
#define ll long long
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
    static char ibuf[RLEN],*ib,*ob;
    (ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    return (ib==ob)?EOF:*ib++;
}
inline int read(){
    char ch=gc();
    int res=0;bool f=1;
    while(!isdigit(ch))f^=ch=='-',ch=gc();
    while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    return f?res:-res;
}
inline ll readll(){
    char ch=gc();
    ll res=0;bool f=1;
    while(!isdigit(ch))f^=ch=='-',ch=gc();
    while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    return f?res:-res;
}
inline int readstring(char *s){
	int top=0;char ch=gc();
	while(isspace(ch))ch=gc();
	while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
	return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<typename tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
cs int mod=1e9+7;
inline int add(int a,int b){return (a+b)>=mod?(a+b-mod):(a+b);}
inline int dec(int a,int b){return (a<b)?(a-b+mod):(a-b);}
inline int mul(int a,int b){static ll r;r=(ll)a*b;return (r>=mod)?(r%mod):r;}
inline void Add(int &a,int b){a=(a+b)>=mod?(a+b-mod):(a+b);}
inline void Dec(int &a,int b){a=(a<b)?(a-b+mod):(a-b);}
inline void Mul(int &a,int b){static ll r;r=(ll)a*b;a=(r>=mod)?(r%mod):r;}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
inline int Inv(int x){return ksm(x,mod-2);}
inline int fix(int x){return (x<0)?x+mod:x;}
cs int N=100005;
int iv[N],s[3005][3005];
inline void init_fac(){
	s[0][0]=1;
	for(int i=1;i<=3000;i++){
		for(int j=1;j<=i;j++)
		s[i][j]=add(s[i-1][j-1],mul(s[i-1][j],j));
	}iv[0]=iv[1]=1;
	for(int i=2;i<N;i++)iv[i]=mul(mod-mod/i,iv[mod%i]);
}
int n,k,Q;
int main(){
	freopen("lx.in","r",stdin);
	n=read(),k=read(),Q=read();
	init_fac();
	if(k==0){
		cout<<mul(mul(Q,n),ksm(Q+1,n-1))<<'\n';return 0;
	}
	int res=0,mt=ksm(Q+1,n),inv=Inv(Q+1),pw=1,pw2=1;
	for(int t=0;t<=k&&t<=n;t++){
		int now=mul(t+1,mt);
		if(t<n)Add(now,mul(mul(n-t,Q),mul(mt,inv)));
		Mul(mt,inv);
		Mul(now,mul(s[k][t],pw));
		Mul(now,iv[t+1]);
		Add(res,mul(now,pw2));
		Mul(pw,n-t),Mul(pw2,Q);
	}
	cout<<res<<'\n';
}

T3:

显然期望是积分一下求得
考虑答案即即 ∏ j ( ∑ i ≥ 0 a j i x i ( i + 1 ) ! ) \prod_{j}(\sum_{i\geq0}\frac{a_j^ix^i}{(i+1)!}) j(i0(i+1)!ajixi)
显然要转 ln ⁡ 后 exp ⁡ \ln后\exp lnexp

开始推的是 ln ⁡ ( e a x − 1 a x ) \ln(\frac{e^{ax}-1}{ax}) ln(axeax1),发现这个没法直接求 ln ⁡ \ln ln
考虑设 f ( x ) = ∑ i x i ( i + 1 ) ! f(x)=\sum_{i}\frac{x^i}{(i+1)!} f(x)=i(i+1)!xi
那就是要求 ∑ j ln ⁡ ( f ( a j x ) ) \sum_j\ln(f(a_jx)) jln(f(ajx))
ln ⁡ ( f ) = ∑ i f i x i \ln(f)=\sum_{i}f_ix^i ln(f)=ifixi
那么就是 ∑ j ∑ i = 0 ∞ f i a j i x i = ∑ i f i x i ∑ j = 1 n a j i \sum_j\sum_{i=0}^{\infty}{f_ia_j^ix^i}=\sum_{i}f_ix^i\sum_{j=1}^na_j^i ji=0fiajixi=ifixij=1naji
就是要求等幂和
直接分治 N T T NTT NTT即可

复杂度 O ( n l o g 2 n ) O(nlog^2n) O(nlog2n)

#include
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair
#define ll long long
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
    static char ibuf[RLEN],*ib,*ob;
    (ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    return (ib==ob)?EOF:*ib++;
}
inline int read(){
    char ch=gc();
    int res=0;bool f=1;
    while(!isdigit(ch))f^=ch=='-',ch=gc();
    while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    return f?res:-res;
}
inline ll readll(){
    char ch=gc();
    ll res=0;bool f=1;
    while(!isdigit(ch))f^=ch=='-',ch=gc();
    while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    return f?res:-res;
}
inline int readstring(char *s){
	int top=0;char ch=gc();
	while(isspace(ch))ch=gc();
	while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
	return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<typename tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
cs int mod=998244353;
inline int add(int a,int b){return (a+b)>=mod?(a+b-mod):(a+b);}
inline int dec(int a,int b){return (a<b)?(a-b+mod):(a-b);}
inline int mul(int a,int b){static ll r;r=(ll)a*b;return (r>=mod)?(r%mod):r;}
inline void Add(int &a,int b){a=(a+b)>=mod?(a+b-mod):(a+b);}
inline void Dec(int &a,int b){a=(a<b)?(a-b+mod):(a-b);}
inline void Mul(int &a,int b){static ll r;r=(ll)a*b;a=(r>=mod)?(r%mod):r;}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
inline int Inv(int x){return ksm(x,mod-2);}
inline int fix(int x){return (x<0)?x+mod:x;}
#define poly vector
namespace Poly{
	cs int C=19,M=(1<<C)|5,G=3;
	int *w[C+1],rev[M],inv[M];
	inline void init_rev(int lim){
		for(int i=0;i<lim;i++)rev[i]=(rev[i>>1]>>1)|((i&1)*(lim>>1));
	}
	inline void init_w(){
		for(int i=1;i<=C;i++)w[i]=new int[(1<<(i-1))|1];
		int wn=ksm(G,(mod-1)/(1<<C));w[C][0]=1;
		for(int i=1,l=(1<<(C-1));i<l;i++)w[C][i]=mul(w[C][i-1],wn);
		for(int i=C-1;i;i--)
		for(int j=0,l=1<<(i-1);j<l;j++)w[i][j]=w[i+1][j<<1];
		inv[0]=inv[1]=1;
		for(int i=2;i<M;i++)inv[i]=mul(mod-mod/i,inv[mod%i]);
	}
	inline void ntt(int *f,int lim,int kd){
		for(int i=0;i<lim;i++)if(i>rev[i])swap(f[i],f[rev[i]]);
		for(int mid=1,l=1,a0,a1;mid<lim;mid<<=1,l++)
		for(int i=0;i<lim;i+=mid<<1)
		for(int j=0;j<mid;j++)
		a0=f[i+j],a1=mul(w[l][j],f[i+j+mid]),f[i+j]=add(a0,a1),f[i+j+mid]=dec(a0,a1);
		if(kd==-1){
			reverse(f+1,f+lim);
			for(int i=0;i<lim;i++)Mul(f[i],inv[lim]);
		}
	}
	inline poly operator *(poly a,poly b){
		int deg=a.size()+b.size()-1;
		if(a.size()<=12||b.size()<=12){
			poly c(deg,0);
			for(int i=0;i<a.size();i++)
			for(int j=0;j<b.size();j++)
			Add(c[i+j],mul(a[i],b[j]));
			return c;
		}
		int lim=1;while(lim<deg)lim<<=1;
		init_rev(lim);
		a.resize(lim),ntt(&a[0],lim,1);
		b.resize(lim),ntt(&b[0],lim,1);
		for(int i=0;i<lim;i++)Mul(a[i],b[i]);
		ntt(&a[0],lim,-1),a.resize(deg);
		return a;
	}
	inline poly Inv(poly a,int deg){
		poly b(1,::Inv(a[0])),c;
		for(int lim=4;lim<(deg<<2);lim<<=1){
			c.resize(lim>>1);
			for(int i=0;i<(lim>>1);i++)c[i]=(i<a.size()?a[i]:0);
			init_rev(lim);
			b.resize(lim),ntt(&b[0],lim,1);
			c.resize(lim),ntt(&c[0],lim,1);
			for(int i=0;i<lim;i++)Mul(b[i],dec(2,mul(b[i],c[i])));
			ntt(&b[0],lim,-1),b.resize(lim>>1);
		}b.resize(deg);return b;
	}
	inline poly deriv(poly a){
		for(int i=0;i+1<a.size();i++)a[i]=mul(a[i+1],i+1);
		a.pop_back();return a;
	}
	inline poly integ(poly a){
		a.pb(0);
		for(int i=a.size()-1;i;i--)a[i]=mul(a[i-1],inv[i]);
		a[0]=0;return a;
	}
	inline poly Ln(poly a,int deg){
		a=integ(Inv(a,deg)*deriv(a)),a.resize(deg);return a;
	}
	inline poly Exp(poly a,int deg){
		poly b(1,1),c;
		for(int lim=2;lim<(deg<<1);lim<<=1){
			c=Ln(b,lim);
			for(int i=0;i<lim;i++)c[i]=dec(i<a.size()?a[i]:0,c[i]);
			Add(c[0],1),b=b*c,b.resize(lim);
		}b.resize(deg);return b;
	}
}using namespace Poly;
cs int N=100005;
int a[N],fac[N],ifac[N];
inline void init_fac(){
	fac[0]=ifac[0]=1;
	for(int i=1;i<N;i++)fac[i]=mul(fac[i-1],i);
	ifac[N-1]=Inv(fac[N-1]);
	for(int i=N-2;i;i--)ifac[i]=mul(ifac[i+1],i+1);
}
poly f[N<<2];
#define lc (u<<1)
#define rc ((u<<1)|1)
#define mid ((l+r)>>1)
void build(int u,int l,int r){
	if(l==r){f[u].pb(1),f[u].pb(dec(0,a[l]));return;}
	build(lc,l,mid),build(rc,mid+1,r);
	f[u]=f[lc]*f[rc];
}

int n,m;
int main(){
	init_fac();init_w();
	n=read(),m=read();
	for(int i=1;i<=n;i++)a[i]=read();
	build(1,1,n);
	poly g(n+1,0),p(m+1,0);
	for(int i=0;i<=m;i++)p[i]=ifac[i+1];
	p=Ln(p,m+1);
	for(int i=0;i<=n;i++)g[i]=mul(f[1][i],n-i);
	g=g*Inv(f[1],m+1);g.resize(m+1);
	for(int i=0;i<=m;i++)Mul(p[i],g[i]);
	p=Exp(p,m+1);
	cout<<mul(p[m],fac[m])<<'\n';
	return 0;
}

你可能感兴趣的:(【2020省选模拟】题解)