专栏文章
题解:CF2150B Grid Counting
CF2150B题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mingl907
- 此快照首次捕获于
- 2025/12/02 02:04 3 个月前
- 此快照最后确认于
- 2025/12/02 02:04 3 个月前
题解:CF2150B Grid Counting
思路
首先,因为题目的第二、三条限制,每个 都对应一个黑色格子,所以黑色格子一共有 个。
首先,我们必须在 和 位置放黑色格子,因为只有他们能满足 时的第二、三条限制。
那么,在 下面的格子就必须都为白色,因为 对于第三条限制的 ,此时 的 为最大值,而在 下面的点的的 ,和 相等,所以不能选,以此类推,在 下面的格子也必须为白色。
接下来考虑第二、三条限制 的情况,因为第 和 列不能选,所以只能选第 和 列中 的格子。
以此类推,最终能选的格子即为下图:

其中黑色为必选的部分,灰色为可选的部分(每列选一个)。
那么接下来我们倒序枚举 到 ,设当前一共可以放的黑色格子数量为 ,每遇到可以放黑色格子的行就将 加上本行加的黑色格子数量,比如到第 行可以多放两个,如果 则无解,每次将答案乘上 即可。
代码
CPP#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
int t,n,a[200010];
ll f[200010];
ll qpow(ll a,ll b){
ll ans=1;
for(;b;b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod;
return ans;
}
ll C(ll n,ll m){
if(n<m)return 0;
return f[n]*qpow(f[m],mod-2)%mod*qpow(f[n-m],mod-2)%mod;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
f[0]=1;
for(int i=1;i<=200000;i++)f[i]=f[i-1]*i%mod;
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int cnt=0,fl=1;
ll ans=1;
for(int i=n;i>=1;i--){
if(i*2==n+1)cnt++;
else if(i*2<=n)cnt+=2;
if(cnt<a[i]){
fl=0;
break;
}
ans=ans*C(cnt,a[i])%mod;
cnt-=a[i];
}
if(cnt!=0||!fl){
cout<<"0\n";
}
else{
cout<<ans<<'\n';
}
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...