比赛 |
2025.5.5 |
评测结果 |
AAAAAAAAAA |
题目名称 |
cake |
最终得分 |
100 |
用户昵称 |
darkMoon |
运行时间 |
1.330 s |
代码语言 |
C++ |
内存使用 |
8.10 MiB |
提交时间 |
2025-05-05 08:34:10 |
显示代码纯文本
#include<bits/stdc++.h>
#define int long long
using namespace std;
auto IN = freopen("cake.in", "r", stdin);
auto OUT = freopen("cake.out", "w", stdout);
auto mread = [](){int x;scanf("%lld", &x);return x;};
const int N = 2005, MOD = 998244353;
int n = mread(), m = mread();
char s[N][N];
int f[N], sum[N];
vector<int> v[N];
set<int> se;
int now;
struct tree{
int s[N << 2][2], fi[N << 2], la[N << 2], siz[N << 2];
void build(int x, int nl, int nr){
if(nl == nr){
s[x][0] = s[x][1] = 1;
fi[x] = la[x] = siz[x] = 0;
return;
}
int mid = nl + nr >> 1;
build(x << 1, nl, mid);
build(x << 1 | 1, mid + 1, nr);
pushup(x);
return;
}
void pushup(int x){
int l = x << 1, r = x << 1 | 1;
if(siz[l] == 0 && siz[r] == 0){
s[x][0] = s[x][1] = 1;
fi[x] = la[x] = siz[x] = 0;
}
else if(siz[l] == 0){
fi[x] = fi[r], la[x] = la[r], siz[x] = siz[r];
s[x][0] = s[r][0], s[x][1] = s[r][1];
}
else if(siz[r] == 0){
fi[x] = fi[l], la[x] = la[l], siz[x] = siz[l];
s[x][0] = s[l][0], s[x][1] = s[l][1];
}
else{
fi[x] = fi[l], la[x] = la[r], siz[x] = siz[l] + siz[r];
if(siz[l] & 1){
// siz[l] 是奇数,意味着左边是从奇数开始,到右边就变成了从偶数开始,反之亦然
s[x][1] = s[l][1] * s[r][0] % MOD * (fi[r] - la[l]) % MOD;
s[x][0] = s[l][0] * s[r][1] % MOD;
}
else{
s[x][1] = s[l][1] * s[r][1] % MOD;
s[x][0] = s[l][0] * s[r][0] % MOD * (fi[r] - la[l]) % MOD;
}
}
return;
}
void add(int x, int nl, int nr, int p){
if(nl == nr){
siz[x] ++;
fi[x] = la[x] = nl;
if(siz[x] == 1){
s[x][0] = s[x][1] = 1;
}
else{
s[x][0] = 1;
s[x][1] = 0;
}
return;
}
int mid = nl + nr >> 1;
if(p <= mid){
add(x << 1, nl, mid, p);
}
else{
add(x << 1 | 1, mid + 1, nr, p);
}
pushup(x);
return;
}
}t;
bool add(int x){
sum[x] ++;
if(sum[x] > 2){
return 0;
}
t.add(1, 1, m, x);
return 1;
}
signed main(){
for(int i = 1; i <= n; i ++){
scanf("%s", s[i] + 1);
for(int j = 1; j <= m; j ++){
if(s[i][j] == 'Y'){
v[i].push_back(j);
}
}
}
f[0] = 1;
for(int i = 1; i <= n; i ++){
int ts = 0;
now = 1;
memset(sum, 0, sizeof(sum));
t.build(1, 1, m);
for(int j = i; j >= 1; j --){
ts += v[j].size();
int e = 1;
// j 到 i 行划分到一起
for(int x : v[j]){
if(!add(x)){
e = 0;
break;
}
}
if(e == 0){
break;
}
if(ts & 1);
else if(ts != 0){
(f[i] += f[j - 1] * t.s[1][0] % MOD) %= MOD;
}
}
}
printf("%lld\n", f[n]);
return 0;
}