比赛 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;
}