多项式练习记录(2)

整天推期望式子人都快薛定谔了,来写写多项式

终于摆脱了会多项式不会生成函数的困境XD

P6913 Tile Cutting

在一个方格纸上切出给定大小的平行四边形。要求必须有一条边在左下角(不能用方格纸顶点),且平行四边形四个端点在四条边上。求区间中切割方案数最多的最小值。


以题面中 B 图为例,设横竖边长为 \(h,l\) ,左下角边长为 \(x,y\) ,比如这里就是 \(h=2,l=4,x=1,y=3\) . 令当前面积为 \(S\) ,有 \(S=hl-xy-(h-x)(l-y)\) ,化简得到 \(S=x(l-y)+y(h-x)\) . 由于这里 \(h,l,x,y\) 全是任意的,所以 \((l-y),(h-x)\) 这样的东西也可以认为是随意取值。

所以可以设 \(h[i]\) 表示 \(xy=i\) 的方案数,那么 \(f[S]\) 就直接用 \(h\) 卷积就好了。最大值就直接ST表。

WF就这?

//Author: RingweEH
using namespace Poly;
using namespace ST_table;

int g[M];

int main()
{
	for ( int i=1; i<=N-10; i++ )
		for ( int j=1; i*j<=N-10; j++ )
			g[i*j]++;

//--------------Convolution-----------------
	Poly_Init((N-10)<<1); NTT( g,1 );
	for ( int i=0; i<Poly::lim; i++ ) g[i]=1ll*g[i]*g[i]%Mod;
	reverse(g+1,g+Poly::lim); NTT(g,0);
//--------------ST--------------
	ST_Init(N-10,g);
	int T=read();
	while ( T-- )
	{
		int l=read(),r=read();
		Query(l,r);
	}
	
	return 0;
}

CF623E Transforming Sequence

对于 \(a\) ,定义 \(b_i=a_1|a_2|\cdots|a_i\) ,求有多少长度为 \(n\)\(1\leq a_i\leq 2^k-1\) 的序列 \(a\) 使得 \(b\) 严格单增。


每次至少要多一位 1 还得严格……所以 \(n>k\) 必然无解。于是题意变成了:

\(n\) 次,每次选一个元素在 \([1,k]\) 的集合,要求选出来的集合与之前的至少有一个不同元素,求方案。(相当于二进制拆位)

\(dp[n][k]\) 表示取了 \(n\) 次,用了 \(k\) 种元素的方案数。注意要钦定 \(k\) 种的具体方案,最后统计再乘个 \(\displaystyle\binom ki\) 就好了,不然不好转移。

\[dp[i][j]=\sum_{l=0}^{j-1}dp[i-1][l]\binom{j}{l}2^i \]

\(k\leq 3e4\) ,果断上倍增FFT:

\[\begin{cases} dp[n+1][j]=\sum\limits_{i=0}^{j-1}dp[n][i]\binom ji2^i\\\\ dp[2n][j]=\sum\limits_{i=0}^{j-1}dp[n][i]dp[n][j-i]\binom ji2^{ni} \end{cases} \]

第一次写拆系数的 MTT QWQ

//Author: RingweEH
const int N=3e4+10,M=N<<2,Mod=1e9+7;
using namespace Math;
namespace Poly
{
#define Clear(a,n) memset(a,0,sizeof(int)*(n))
#define Copy(a,b,n) memcpy(a,b,sizeof(int)*(n))
#define Rev(a,b) reverse(a,b)
	const db PI=acos(-1.0);
	int rev[M],lg,lim;
	struct Complex
	{
		db x,y;
		Complex( db _x=0,db _y=0 ) : x(_x),y(_y) {}
		Complex operator + ( const Complex &tmp ) const { return Complex(x+tmp.x,y+tmp.y); }
		Complex operator - ( const Complex &tmp ) const { return Complex(x-tmp.x,y-tmp.y); }
		Complex operator * ( const Complex &tmp ) const
		{ return Complex(x*tmp.x-y*tmp.y,x*tmp.y+y*tmp.x); }
	}w[M];
	void Poly_Init( int n )
	{
		for ( lim=1,lg=0; lim<=n; lim<<=1,lg++ );
		for ( int i=0; i<lim; ++i ) 
			rev[i]=(rev[i>>1]>>1) | ((i&1)<<(lg-1)),w[i]=Complex(cos(2*PI*i/lim),sin(2*PI*i/lim));
	}
	void FFT( Complex *f,int opt )
	{
		for ( int i=0; i<lim; ++i )
			if ( i>rev[i] ) swap( f[i],f[rev[i]] );
		for ( int i=1,len=lim>>1; i<lim; i<<=1,len>>=1 )
			for ( int j=0; j<lim; j+=(i<<1) )
				for ( int k=0; k<i; ++k )
				{
					Complex t1=f[j+k],t2=w[len*k]*f[i+j+k];
					f[j+k]=t1+t2; f[i+j+k]=t1-t2;
				}
		if ( opt ) return;
		for ( int i=0; i<lim; ++i ) f[i].x/=lim;
	}
	void MTT( int *f,int *g,int *res )
	{
		static Complex A[M],B[M],C[M],D[M],E[M],F[M],G[M];
		static int cs1=65535,cs2=16;
		for ( int i=0; i<lim; ++i )
		{
			A[i]=Complex(f[i]&cs1,0); B[i]=Complex(f[i]>>cs2,0);
			C[i]=Complex(g[i]&cs1,0); D[i]=Complex(g[i]>>cs2,0);
		}
		FFT(A,1); FFT(B,1); FFT(C,1),FFT(D,1);
		for ( int i=0; i<lim; ++i )
		{
			E[i]=A[i]*C[i]; F[i]=A[i]*D[i]+B[i]*C[i];
			G[i]=B[i]*D[i]; w[i].y*=-1;
		}
		FFT(E,0); FFT(F,0); FFT(G,0);
		for ( int i=0; i<lim; ++i )
		{
			res[i]=(ll)(G[i].x+0.5)%Mod;
			res[i]=((1ll*(cs1+1)*res[i]%Mod)+(ll)(F[i].x+0.5)%Mod)%Mod;
			res[i]=((1ll*(cs1+1)*res[i]%Mod)+(ll)(E[i].x+0.5)%Mod)%Mod;
			w[i].y*=-1;
		}
	}
	void Movement( int n,int len,int *f )
	{
		static int tf[M],tg[M];
		Clear(tf,lim); Clear(tg,lim);
		for ( int i=0,t=power(2,len),j=1; i<n; i++,j=1ll*j*t%Mod )
			tf[i]=1ll*f[i]*j%Mod*infac[i]%Mod;
		for ( int i=1; i<=n; i++ ) tg[i]=1ll*f[i]*infac[i]%Mod;
		MTT( tf,tg,f );
		for ( int  i=0; i<=n; i++ ) f[i]=1ll*f[i]*fac[i]%Mod;
		Clear(f+n+1,lim-n);
	}
	void SetBit( int n,int *f )
	{
		static int tf[M],tg[M];
		Clear(tf,lim); Clear(tg,lim);
		for ( int i=0,j=1; i<n; i++,(j<<=1)%=Mod ) tf[i]=1ll*f[i]*j%Mod*infac[i]%Mod;
		for ( int i=1; i<=n; i++ ) tg[i]=infac[i];
		MTT( tf,tg,f );
		for ( int i=0; i<=n; i++ ) f[i]=1ll*f[i]*fac[i]%Mod;
		Clear(f+1+n,lim-n);
	}
};
using namespace Poly;
int n,k,F[M];

int main()
{
	ll qwq; scanf( "%lld%d",&qwq,&k );
	if ( qwq>k ) { puts("0"); return 0; }
	n=qwq; F[0]=0; 
	for ( int i=1; i<=k; i++ ) F[i]=1;
	Poly_Init(k<<1); Init(k);
	for ( int i=log2(n)-1,len=1; i>=0; i-- )
	{
		Movement(k,len,F); len<<=1;
		if ( n>>i&1 ) SetBit(k,F),len++;
	}
	
	int ans=0;
	for ( int i=n; i<=k; i++ )
		ans=(ans+1ll*F[i]*fac[k]%Mod*infac[i]%Mod*infac[k-i]%Mod)%Mod;
	printf( "%d\n",ans );

	return 0;
}

不想打 分治 / 倍增 / MTT 了,所以要做生成函数

P4389 付公主的背包

给定 \(n\) 个物品的体积,不限量,求恰好装 \([1,m]\) 体积的方案数。


我想了半天为什么这个东西不能按照骨牌那样直接做然后发现它:没有标号!我从未如此渴望标号

所以就只能把 \(m\) 个式子卷起来了。这太不讲理了,显然不行。

对于一个体积为 \(v_i\) 的物品,式子就是

\[A_k(x)=\sum [i\bmod v_k=0]x^i=\sum x^{iv_k}=\dfrac{1}{1-v_k} \]

然后发现一打 \(-1\) 次幂,所以 \(\tt ln+exp\) 无敌啦,直接化成加法。常用套路

剩下的式子直接推就好了。

\[A'(x)=\dfrac{B'(x)}{B(x)}=(1-x^v)(\sum vi\ x^{vi-1})=\sum v\ x^{vi-1}\\\\ A(x)=\sum \dfrac{x^{vi}}{i} \]

于是就没了。

进了最优解第一页却怎么都上不去了…… /dk

//Author: RingweEH
int n,m,cnt[N],F[N],G[M];

int main()
{
	n=read(); m=read()+1; Math::Init();
	for ( int i=1,x; i<=n; i++ ) x=read(),cnt[x]++;
	
	for ( int i=1; i<m; i++ )
	{
		if ( !cnt[i] ) continue;
		for ( int j=1; i*j<m; j++ )
			bmod(F[i*j]+=1ll*cnt[i]*Math::inv[j]%Mod);
	}
	Poly::Poly_Exp(m,F,G);
	
	for ( int i=1; i<m; i++ ) printf( "%d\n",G[i] );

	return 0;
}

P4491 染色

一个长度为 \(n\) 的序列染 \(m\) 种颜色,设每种方案中出现次数恰好为 \(S\) 的颜色有 \(k\) 种,求 \(w_k\) 之和。


\(1004535809\) 良心模数好评!虽然我还是不会 看到恰好反手就是一个容斥。然后暴毙

其实这题有俩容斥:恰好 \(S\) 次,恰好 \(k\) 种。然后其实是要容斥后一个的。

\(F[k]\) 表示有至少 \(k\) 个颜色恰好出现了 \(S\) 次。钦定出现,剩下随意,有

\[F[k]=\binom{m}{k}\dfrac{\binom{n}{Sk}(Sk)!}{(S!)^{k}}(m-k)^{n-Sk} \]

\(G[k]\) 表示恰好 \(k\) 个颜色恰好出现了 \(S\) 次,有

\[F[k]=\sum \binom ikG[i]=>G[k]=\sum (-1)^{i-k}\binom ikF[i] \]

然后化简一下,翻转之后卷起来就好了。

注意事项就是阶乘及其逆元不要开小了。

//Author: RingweEH
int n,m,S,F[M],G[M],w[N],tf[M],tg[M];

int main()
{
	n=read(); m=read(); S=read(); int lim=min(n/S,m); Init();
	for ( int i=0; i<=m; i++ ) w[i]=read();
	
	for ( int i=0; i<=lim; i++ )
		F[i]=1ll*Binom(m,i)*fac[n]%Mod*power(infac[S],i)%Mod*infac[n-S*i]%Mod*power(m-i,n-S*i)%Mod;
	for ( int i=0; i<=lim; i++ )
		tf[i]=1ll*fac[lim-i]*F[lim-i]%Mod;
	for ( int i=0; i<=lim; i++ )
		F[i]=(i&1) ? Mod-infac[i] : infac[i];
	Poly::Poly_Mul(lim+1,lim+1,F,tf,tg);
	for ( int i=0; i<=lim; i++ ) 
		G[i]=1ll*infac[i]*tg[lim-i]%Mod;
		
	int ans=0;
	for ( int i=0; i<=lim; i++ )
		bmod( ans+=1ll*G[i]*w[i]%Mod );

	printf( "%d\n",ans );

	return 0;
}

P4463 calc

称一个序列合法,当且仅当长度为 \(n\)\(a_i\in[1,k]\) 且互不相等。其值为所有数的乘积。求所有合法序列权值之和。


把答案写成生成函数:

\[F(x)=\prod_{i=1}^k(1+ix) \]

此时无序,所以还要乘一个阶乘,最终答案是 \(n![x^n]F(x)\) . 然后按套路 \(\tt ln+exp\) 积化和:

\[A(x)=\ln(1+kx)=>A'(x)=\dfrac{k}{1+kx}=\dfrac{-(-k)}{1-(-kx)}=-\sum\limits_{i=0}(-k)(-kx)^i\\\\ A(x)=-\sum_{i=1}\dfrac{(-kx)^i}{i}=\sum_{i=1}\dfrac{k^i(-1)^{i+1}}{i}x^i \]

有结论:\(\ln(1-x)=-\sum_{i=1} \dfrac{x^i}{i}\)

然后枚举 \(i\) ,改变求和方向(其实就是,本来是固定 \(k\) 枚举 \(i\) ,现在换了一下,反正 \(k\) 也是连续的)

\[\dfrac{(-1)^{i+1}}{i}\sum_{j=1}^{k}j^i \]

问题转化为求自然数幂前缀和,拉格朗日插值即可。

//Author: RingweEH
int Lagrange( int n,int k )	//1^k...n^k
void Poly_Exp( int n,int *f,int *g )

int n,k,F[N],G[N];

int main()
{
	k=read(); n=read(); Mod=read(); Init();
	
	for ( int i=1; i<=n; i++ )
		F[i]=1ll*Lagrange(k,i)*(i&1 ? inv[i] : Mod-inv[i])%Mod;
	Poly_Exp(n+1,F,G);
	
	printf( "%lld\n",1ll*G[n]*fac[n]%Mod );

	return 0;
}

P5860 Counting Trees

\(n\) 个点和权值 \(v_i\) ,从中选出一些点组成一个集合,使之能形成一棵树且 \(d_i\) 的度数为 \(v_{d_i}\) ,求方案数。


学习英语:supercalifragilisticexpialidocious ,“极好的;奇妙的;难以置信的”

跟度数有关,那首先把满足条件的度数式子写出来。有 \(\sum(2-v_{d_i})=2\) ,然后设生成函数就是 \(1+x^{2-v_{d_i}}\) ,最后就是求 \([x^2]\) 项。但是这样系数是负数。不妨把所有幂次取负,也就是 \(\sum (v_{d_i}-2)=-2\) ,所求项转化为 \(x^{-2}\) .

我仿佛懂得了。要算这个东西还是得大力分讨。对于 \(v_{d_i}\)(以下简称 \(v_i\) ),分三类:

  • \(v_i=2\) :设有 \(cnt_2\) 个,最后乘上 \(2^{cnt_2}\)
  • \(v_i=1\) :设正常得到的结果是 \(F\) ,这类有 \(cnt_1\) 个,现在要统计上 \(v_i=1\) 的部分,答案就是 \(\sum\limits_{i=2}\binom{cnt_1}{i}F[i-2]\) ,因为每个值为 \(i\) 的都要用 \(i+2\)\(-1\) 次幂把它消成 \([x^{-2}]\)
  • 至于 \(v_i>2\) ,显然是套路 \(\tt ln+exp\) ,用之前那个式子 \(\ln(1-x)=-\sum_{i=1} \dfrac{x^i}{i}\) ,把 \(1+x^v\) 带进去,然后统计 \(v\) 的分布暴力乘上去就好了。

好像也不难 @tommy0221 的最优解被我挤下去了 /cy 做题号交了一发直接碾压了 100ms ,然后大号经过不懈努力趁着公开赛期间波动卡到了 791ms 我也不知道为什么公开赛会突然波动快了,之前一直和做题号差了几毫秒

//Author: RingweEH
using namespace Math;
using Poly :: Poly_Exp;

int n,cnt[N],F[M],G[M];

int main()
{
	n=read(); int i,j,x;
	for ( i=1; i<=n; i++ ) x=read(),cnt[x]++;
	
	Init(); 
	for ( i=1; i<cnt[1]; i++ )
		for ( j=1; i*j<cnt[1]; j++ )
			if ( j&1 ) bmod( F[i*j]+=1ll*cnt[i+2]*inv[j]%Mod );
			else bmod( F[i*j]+=1ll*(Mod-cnt[i+2])*inv[j]%Mod );
	Poly_Exp( cnt[1],F,G );
	
	int ans=0;
	for ( i=2; i<=cnt[1]; i++ )
		bmod( ans+=1ll*binom(cnt[1],i)*G[i-2]%Mod );
	ans=1ll*ans*power(2,cnt[2])%Mod;
	printf( "%d\n",ans );

	return 0;
}

P5401 珍珠

一个长度为 \(n\),元素取值 \(\in [1,D]\) 的整数序列合法,当且仅当其中能够选出至少 \(m\) 对相同元素(不能重复选出元素)。问合法序列个数。


刚看到这个题目以为又是什么给指导和手串的故事 ☞ Burnside 之类的置换计数。

转化题意,设对于值为 \(x\) 的元素,在序列中的个数为 \(cnt_x\) ,那么题目要求就是 \(\displaystyle\sum\Big\lfloor \dfrac{cnt_x}2\Big\rfloor\ge m\)

稍微化一下式子就是:\(n-2m\ge \sum (cnt_x\bmod 2)\) ,那么 \(D\leq n-2m\) 必然有解。而个数为偶数的 EGF 在 “染色问题” 里面提到过,就是 \(\dfrac{e^x+e^{-x}}2\) .

\(F(k)\) 表示 \(k\) 个是偶数的情况,有

\[F(k)=\binom Dk[x^n]\left(\dfrac{e^x+e^{-x}}{2}\right)^k(e^x)^{D-k}=\dfrac{\binom Dk}{2^k}[x^n]\sum_{i=0}^k\binom ki(e^x)^{D-2k+2i} \]

然后令 \(G(k)\) 表示恰好 \(k\) 个是偶数,二项式反演上去

\[F(k)=\sum_{i=k}^D\binom ikG(i)=>G(k)=\sum_{i=k}^D\binom ik(-1)^{i-k}F(i) \]

剩下的任务就是要把 \(F\) 搞出来,然后暴力累加区间范围内的 \(G\) 就好了。

基本 EGF 里有 \(\{1,c,c^2,\cdots \}\xrightarrow{EGF}e^{cx}\) ,所以

\[[x^n]\sum_{i=0}^k\binom ki(e^x)^{D-2k+2i}=\sum_{i=0}^k\binom ki\dfrac{(D-2k+2i)^n}{n!}=k!\sum_{i=0}^k\dfrac 1{i!}\dfrac{(D-2(k-i))^n}{(k-i)!} \]

卷就完了!

//Author: RingweEH
using namespace Math;
using namespace Poly;

int D,n,m,F[M],G[M];

int main()
{
	Init();
	D=read(); n=read(); m=read();
	
	int i,j;
	for ( i=0; i<=D; i++ ) F[i]=infac[i];
	for ( i=0; i<=D; i++ ) G[i]=bmod(1ll*power(D-2*i,n)*infac[i]%Mod+Mod);
	Poly_Mul(D+1,D+1,F,G,F);
	for ( i=0; i<=D; i++ ) F[i]=1ll*F[i]*fac[i]%Mod;
	for ( i=0,j=1; i<=D; i++,j=1ll*j*inv[2]%Mod ) 
		F[i]=1ll*binom(D,i)*j%Mod*F[i]%Mod;
	for ( i=0; i<=D; i++ ) F[i]=1ll*F[i]*fac[i]%Mod;
	for ( i=0; i<=D; i++ ) G[i]=(i&1) ? Mod-infac[i] : infac[i];
	reverse( G,G+1+D ); Poly_Mul(D+1,D+1,F,G,F);
	for ( i=0; i<=D; i++ ) G[i]=1ll*infac[i]*F[D+i]%Mod;
	
	int ans=0;
	for ( i=max(0,D-(n-2*m)); i<=D; i++ ) ans=bmod(ans+G[i]);
	printf( "%d\n",ans );

	return 0;
}

CF923E Perpetual Subtraction

有一个整数 \(x\) ,初始为 \([0,n]\) 的某一个整数,为 \(i\) 的概率为 \(p_i\) ,每一轮可以随机替换成 \([0,x]\) 中的一个数,求 \(m\) 轮之后,对于 \(i\in [0,n]\)\(x=i\) 的概率。


先来个 \(\mathcal{O(n^2m)}\) 的DP,设 \(f[i][j]\) 表示第 \(i\)\(x=j\) 的概率,直接转移就好了

\[f[i][j]=\sum_{i=j}^n\dfrac{f[i-1][j]}{j+1} \]

然后对着这个式子就能造出一个生成函数来:\(F_k(x)=\sum f[k][i]x^i\) .

根据上面的DP式子,写出递推式:

\[\begin{aligned} F_{k+1}(x)&=\sum_{i=0}^n\sum_{j=i}^n\dfrac{f[k][j]}{j+1}x^i =\sum_{j=1}^n\dfrac{f[k][j]}{j+1}\dfrac{x^{j+1}-1}{x-1}\\\\ &=\dfrac{1}{x-1}\sum_{j=1}^n f[k][j]\int_1^xt^jdt =\dfrac{\int_1^x F_k(t)}{x-1} \end{aligned} \]

然而这个积分下界是 \(1\) ,还除了个 \(x-1\) 非常难看,所以考虑平移一下

\[G_{k+1}(x)=F_{k+1}(x+1)=\dfrac{\int_1^{x+1}F_k(t)}{x}=\dfrac{\int_0^xG_k(t)}{x} \]

于是 \(g[k+1][i]=\dfrac{g[k][i]}{i+1},g[m][i]=\dfrac{g[0][i]}{(i+1)^m}\) .

再根据平移列一个式子出来:

\[G_k(x)=F_k(x+1)=\sum_{i=0}^nf[k][i]\sum_{j=0}^i\binom ijx^j=>g[k][i]=\sum_{j=i}^n\binom jif[k][j] \]

二项式反演:

\[f[k][i]=\sum_{j=i}^n(-1)^{j-i}\binom{j}{i}g[k][j] \]

\(f[0][i]\) 已知,然后推出 \(g[0][i]\) 算出 \(g[m][j]\) ,再卷成 \(f\) 即可。

怎么又最优解了 感觉最优解有一点编译加成,aplqo 如果改 c++17 应该比我快,不过没开 O2 就赶上了卡老师很高兴 /cy

//Author: RingweEH
using namespace Math;
using Poly::Poly_Mul;

int n,F[M],G[M],tf[M],tg[M],P[N];
ll m;

int main()
{
	scanf( "%d%lld\n",&n,&m ); m%=(Mod-1); Init();
	for ( int i=0; i<=n; i++ ) P[i]=read();
	
	for ( int i=0; i<=n; i++ ) tf[i]=1ll*fac[i]*P[i]%Mod;
	for ( int i=0; i<=n; i++ ) tg[i]=infac[n-i];
	Poly_Mul(n+1,n+1,tf,tg,tf);
	for ( int i=0; i<=n; i++ ) 
		G[i]=1ll*tf[n+i]*infac[i]%Mod*power(inv[i+1],m)%Mod;

	for ( int i=0; i<=n; i++ ) 
		tf[i]=1ll*fac[i]*G[i]%Mod*(i&1 ? Mod-1 : 1)%Mod;
	for ( int i=0; i<=n; i++ ) tg[i]=infac[n-i];
	Poly_Mul(n+1,n+1,tf,tg,tf);
	for ( int i=0; i<=n; i++ ) 
		F[i]=1ll*tf[n+i]*(i&1 ? Mod-infac[i] : infac[i])%Mod;
	
	for ( int i=0; i<=n; i++ ) printf( "%d ",F[i] );

	return 0;
}

51Nod1514 美妙的序列

称满足如下条件的排列为美妙的:

  • 对于任意 \(k=1\sim n-1\) ,后面 \(n-k\) 个数中至少有一个数不大于左边的数。

多项式复健训练。注意到上面的条件就是 \(k\) 左边不是一个 \(1\sim k\) 的排列。那么可以考虑 DP.

\(f[i]\) 为长度为 \(i\) 的答案,有 \(f[n]=n!-\sum_{i=1}^{n-1}i!\cdot f[n-i]\) .

一般分治FFT能做的求逆都能做。

然后有 \(\sum_{i=1}^ni!\cdot f[n-i]=n!\)\(n=1\) 时左边要加一。

\(G=\sum\limits_{i=0}^{\infin}i!\cdot x^i\) ,有 \(F\cdot G+1=G\) ,所以 \(F=1-\dfrac 1G\) .

太久没打了然后又忘记上界加一了……浪费了 51Nod 的下载次数 /fn

//Author:RingweEH
int n,F[M],G[M];

int main()
{
	n=N-10; G[0]=1; n++;
	for ( int i=1; i<=n; i++ ) G[i]=1ll*G[i-1]*i%Mod;
	Poly::Poly_Inv(n,G,F);
	for ( int i=0; i<n; i++ ) F[i]=(Mod-F[i])%Mod; F[0]++;
	int T=read();
	while ( T-- ) printf( "%d\n",F[read()] );

	return 0;
}
posted @ 2021-02-06 13:53  MontesquieuE  阅读(109)  评论(0编辑  收藏  举报