CF1516E - Baby Ehab Plays with Permutations

题目大意

给定一个排列$1-n$,对于每个$i\in[1,k]$,求出恰好操作$i$能够生成的不同排列个数

分析

设排列为$P_i$,考虑对于最终态每个$(i,P_i)$构成的环组进行$dp$

一个长度为$n$的环有$(n-1)!$种可能的排列,且需要至少$n-1$次操作得到

考虑先$dp$求出至少$i$次操作,生成了总长为$j$的环的种类数,合并两个环类似$\text{exp}$计算

偶数操作显然是可以抵消的,并且奇数次操作无法抵消,故还需根据奇偶性累前缀和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

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]);
}