专栏文章

CF2150B Grid Counting 题解

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

文章操作

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

当前评论
0 条
当前快照
1 份
快照标识符
@minsg8fk
此快照首次捕获于
2025/12/02 07:36
3 个月前
此快照最后确认于
2025/12/02 07:36
3 个月前
查看原文
前置知识:乘法原理、组合数、乘法逆元。
题目大意

给出一个 n×nn\times n 的网格,初始全为白色,我们需要将一些单元格涂黑使得:
对于每个 i[1,m]i \displaystyle \in [1,m],假设 (xi,yi)(x_i,y_i) 是被涂成黑色的单元格,对于每一个 kk 需要满足:
  1. kk 行中存在 aka_k 个黑格。
  2. 存在一个索引 ii 使得 max(xi,yi)=k\max(x_i,y_i)=k
  3. 存在一个索引 ii 使得 max(xi,n+1yi)=k\max(x_i,n+1-y_i)=k
我们需要计算有多少种方案使得满足题目的条件。
思路

观察样例:
每个 kk 对应一个黑色单元格,因此黑色单元格的总数必须恰好为 nn。如果给定的 aa 数组之和不为 nn,则方案数直接为 00,我们只需要输出 00 即可。
我们注意到,第二个与第三个条件存在对称性。则对于更一般的情况,由对称性,我们先对于每个 kk 算出可用的位置数 cntk=max(0,n+22k)cnt_k=\max(0,n+2-2k)。然后从 nn11 遍历每个 kk,累计已经用掉的位置(以下记为 usedused),易知剩余可用位置数(为了对应代码,以下记为 cancan)为 max(0,cntkused)\max(0,cnt_k-used)。此时如果 can<akcan<a_k,则当前行无法放置要求的黑色单元格数,直接输出 00 即可;反之,由乘法原理,我们将方案数乘上 (canak)\tbinom{can}{a_k} ,接着更新 usedused 的值,继续遍历。最后输出总方案数即可。
Code

CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5,MOD=998244353;
int T,n;
int fac[N],inv[N],a[N],cnt[N];

int qpow(int x,int y)
{
	int res=1;
	while(y)
	{
		if(y&1)(res*=x)%=MOD;
		(x*=x)%=MOD;
		y>>=1;
	}
	return res;
}

void init()
{
	fac[0]=1;
	for(int i=1;i<N;i++)
		fac[i]=fac[i-1]*i%MOD;
	
	inv[N-1]=qpow(fac[N-1],MOD-2);
	for(int i=N-2;i>=0;i--)
		inv[i]=inv[i+1]*(i+1)%MOD;
}

inline int C(int n,int m){return n<m?0:fac[n]*inv[n-m]%MOD*inv[m]%MOD;}

signed main()
{
	ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	init();
	cin>>T;
	while(T--)
	{
		memset(cnt,0,sizeof(cnt));
		cin>>n;
		int sum=0;
		for(int i=1;i<=n;i++)
			cin>>a[i],sum+=a[i];

		if(sum!=n)
		{
			cout<<0<<'\n';
			continue;
		}

		for(int k=1;k<=n;k++)
		{
			int val=n+2-2*k;
			if(val<0)val=0;
			cnt[k]=val;
		}

		int ans=1,used=0;
		bool flag=1;
		for(int k=n;k>=1;k--)
		{
			int can=cnt[k]-used;
			if(can<0)can=0;
			if(can<a[k])
			{
				flag=0;
				break;
			}
			ans=ans*C(can,a[k])%MOD;
			used+=a[k];
		}

		if(!flag)cout<<"0\n";
		else cout<<ans%MOD<<'\n';
	}
	return 0;
}

评论

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

正在加载评论...