CF1516E - Baby Ehab Plays with Permutations
题目大意
给定一个排列(1-n),对于每个(iin[1,k]),求出恰好操作(i)能够生成的不同排列个数
分析
设排列为(P_i),考虑对于最终态每个((i,P_i))构成的环组进行(dp)
一个长度为(n)的环有((n-1)!)种可能的排列,且需要至少(n-1)次操作得到
考虑先(dp)求出至少(i)次操作,生成了总长为(j)的环的种类数,合并两个环类似( ext{exp})计算
偶数操作显然是可以抵消的,并且奇数次操作无法抵消,故还需根据奇偶性累前缀和
const int N=410,P=1e9+7;
int n,m;
ll qpow(ll x,ll k=P-2){
ll res=1;
for(;k;k>>=1,x=x*x%P) if(k&1) res=res*x%P;
return res;
}
int C[N][N],F[N],D[N],I[N],J[N];
int dp[N][N];
int main(){
n=rd(),m=rd();
rep(i,0,N-1) rep(j,*C[i]=1,i) C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;
I[0]=I[1]=J[0]=J[1]=1;
rep(i,2,N-1) {
J[i]=1ll*J[i-1]*i%P;
I[i]=1ll*(P-P/i)*I[P%i]%P;
}
// D[i]=C(n,i)
D[0]=1;
rep(i,1,min(m*2,n)) D[i]=1ll*D[i-1]*(n-i+1)%P*I[i]%P;
rep(i,1,N-1) I[i]=1ll*I[i-1]*I[i]%P;
dp[0][0]=1;
rep(i,0,m) rep(j,0,i*2) if(dp[i][j]) rep(k,1,m-i) {
// 生成了k+1个数
// C[j+k+1][j] 组合,强制一个元素在第一位
// J[k] 环排列
dp[i+k][j+k+1]=(dp[i+k][j+k+1]+1ll*dp[i][j]*C[j+k][j]%P*J[k])%P;
}
rep(i,0,m) rep(j,0,i*2) if(dp[i][j]) F[i]=(F[i]+1ll*D[j]*dp[i][j])%P;
rep(i,2,m) F[i]+=F[i-2],Mod1(F[i]);
rep(i,1,m) printf("%d ",F[i]);
}