专栏文章

ARC118E Avoid Permutations 题解

AT_arc118_e题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@minasng0
此快照首次捕获于
2025/12/01 23:22
3 个月前
此快照最后确认于
2025/12/01 23:22
3 个月前
查看原文
直接做有点困难,因此考虑钦定一些尚未确定的障碍点在路径上。设被钦定的障碍点的集合为 TT 时,满足条件的路径数为 c(T)c(T),则根据容斥原理可知答案可以表示为 T(1)Tc(T)\sum_{T} (-1)^{|T|} c(T)
fi,j,k,0/1,0/1f_{i,j,k,0/1,0/1} 表示,考虑到第 ii 行第 jj 列的格子,此时一共钦定了 kk 个障碍点,第 ii 行没有 / 有障碍点,第 jj 列没有 / 有障碍点时的方案数。初始时 f0,0,0,1,1=1f_{0,0,0,1,1}=1
xi=0/1x_i=0/1 表示第 ii 行没有 / 有确定的障碍点,yj=0/1y_j=0/1 表示第 jj 列没有 / 有确定的障碍点。对于 fi,j,k,a,bf_{i,j,k,a,b},考虑转移:
  • 如果 (i,j)(i,j) 处有障碍点,则不做转移;
  • 如果 (i,j)(i,j) 处没有障碍点:
    • 如果 ini \le n
      • 不在 (i,j)(i,j) 处钦定障碍点,fi+1,j,k,xi+1,bfi+1,j,k,xi+1,b+fi,j,k,a,bf_{i+1,j,k,x_{i+1},b} \leftarrow f_{i+1,j,k,x_{i+1},b}+f_{i,j,k,a,b}
      • 如果 a=0a=0b=0b=0:在 (i,j)(i,j) 处钦定障碍点,fi+1,j,k+1,xi+1,1fi+1,j,k+1,xi+1,1+fi,j,k,a,bf_{i+1,j,k+1,x_{i+1},1} \leftarrow f_{i+1,j,k+1,x_{i+1},1}+f_{i,j,k,a,b}
    • 如果 jnj \le n
      • 不在 (i,j)(i,j) 处钦定障碍点,fi,j+1,k,a,yj+1fi,j+1,k,a,yj+1+fi,j,k,a,bf_{i,j+1,k,a,y_{j+1}} \leftarrow f_{i,j+1,k,a,y_{j+1}}+f_{i,j,k,a,b}
      • 如果 a=0a=0b=0b=0:在 (i,j)(i,j) 处钦定障碍点,fi,j+1,k+1,1,yj+1fi,j+1,k+1,1,yj+1+fi,j,k,a,bf_{i,j+1,k+1,1,y_{j+1}} \leftarrow f_{i,j+1,k+1,1,y_{j+1}}+f_{i,j,k,a,b}
mm 表示初始时 1-1 的数量,答案即为:
k=0m(1)k×fn+1,n+1,k,0,0×(mk)!\sum_{k=0}^m (-1)^k \times f_{n+1,n+1,k,0,0} \times (m-k)!
其中乘 (mk)!(m-k)! 是因为没有被钦定的 pp 可以在剩余的 (mk)(m-k) 个位置任意排列。
时间复杂度 O(n3)\mathcal O(n^3)
C
const int N=205,mod=998244353;
int n,m,a[N],fac[N],f[N][N][N][2][2],ans;
bool vis[N][N],x[N],y[N];
void add(int &a,int b){
	a+=b;
	if(a>=mod) a-=mod;
}
void solve(){
	cin>>n,fac[0]=1,f[0][0][0][1][1]=1;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		if(a[i]!=-1) vis[i][a[i]]=1,x[i]=1,y[a[i]]=1;
		else m++;
	}
	for(int i=1;i<=m;i++) fac[i]=1ll*fac[i-1]*i%mod;
	for(int i=0;i<=n+1;i++){
		for(int j=0;j<=n+1;j++){
			if(vis[i][j]) continue;
			for(int k=0;k<=min(i,j);k++){
				for(int a=0;a<=1;a++){
					for(int b=0;b<=1;b++){
						if(i<=n){
							add(f[i+1][j][k][x[i+1]][b],f[i][j][k][a][b]);
							if(!a&&!b) add(f[i+1][j][k+1][x[i+1]][1],f[i][j][k][a][b]);
						}
						if(j<=n){
							add(f[i][j+1][k][a][y[j+1]],f[i][j][k][a][b]);
							if(!a&&!b) add(f[i][j+1][k+1][1][y[j+1]],f[i][j][k][a][b]);
						}
					}
				}
			}
		}
	}
	for(int k=0;k<=m;k++){
		if(k&1) add(ans,mod-1ll*f[n+1][n+1][k][0][0]*fac[m-k]%mod);
		else add(ans,1ll*f[n+1][n+1][k][0][0]*fac[m-k]%mod);
	}
	cout<<ans<<endl;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...