记录编号 577222 评测结果 AAAAAAAAAAAAAAAAAAAAAAAAA
题目名称 [CSP 2019S]Emiya家今天的饭 最终得分 100
用户昵称 Gravatarlihaoze 是否通过 通过
代码语言 C++ 运行时间 0.813 s
提交时间 2022-10-27 01:02:05 内存使用 2.74 MiB
显示代码纯文本
#include "bits/stdc++.h"

using i64 = long long;
 
constexpr int P = 998244353;
 
int norm(int x) {
    if (x < 0) 
        x += P;
    if (x >= P)
        x -= P;
    return x;
}
 
template <class T>
T power(T a, i64 b) {
    T res = 1;
    for (; b; b /= 2, a *= a)
        if (b % 2)
            res *= a;
    return res;
}
 
struct Z {
    i64 x;
    Z (int x = 0) : x(norm(x)) { }
    Z (i64 x) : x(norm(x % P)) { }
    int val() const {
        return x;
    }
    Z inv() const {
        assert(x != 0);
        return power(*this, P - 2);
    }
    Z & operator *= (const Z &rhs) {
        x = i64(x) * rhs.x % P;
        return *this;
    }
    Z & operator += (const Z &rhs) {
        x = norm(x + rhs.x);
        return *this;
    }
    Z & operator -= (const Z &rhs) {
        x = norm(x - rhs.x);
        return *this;
    }
    Z & operator /= (const Z &rhs) {
        return *this *= rhs.inv();
    }
    friend Z operator * (const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res *= rhs;
        return res;
    }
    friend Z operator + (const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res += rhs;
        return res;
    }
    friend Z operator - (const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res -= rhs;
        return res;
    }
    friend Z operator / (const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res /= rhs;
        return res;
    }
    friend std::istream & operator >> (std::istream &is, Z &a) {
        i64 v;
        is >> v;
        a = Z(v);
        return is;
    }
    friend std::ostream & operator << (std::ostream &os, const Z &a) {
        return os << a.val();
    }
};

constexpr int N = 110, M = 2010;
int n, m;
Z tot, a[N][M], f[N][2 * N], s[N] = { 1 }, cnt[N];

int main() {
    freopen("2019meal.in", "r", stdin); 
    freopen("2019meal.out", "w", stdout);
    std::cin >> n >> m;
    for (int i = 1; i <= n; ++ i) 
        for (int j = 1; j <= m; ++ j) 
            std::cin >> a[i][j];
    for (int i = 1; i <= n; ++ i) {
        for (int j = 1; j <= m; ++ j) 
            cnt[i] += a[i][j];
        for (int j = n; j >= 1; -- j) 
            s[j] += s[j - 1] * cnt[i];
    }
    for (int i = 1; i <= n; ++ i)
        tot += s[i];
    for (int i = 1; i <= m; ++ i) {
        memset(f, 0, sizeof f);
        f[0][n] = 1;
        for (int j = 1; j <= n; ++ j) 
            for (int k = n - j; k <= n + j; ++ k) 
                f[j][k] = f[j - 1][k] + f[j - 1][k - 1] * a[j][i] + f[j - 1][k + 1] * (cnt[j] - a[j][i]);
        for (int j = 1; j <= n; ++ j)
            tot -= f[n][n + j];
    }
    std::cout << tot << '\n';
    return 0;
}