# BZOJ5340: [Ctsc2018]假面【概率+期望】【思维】

## 思路

j等于0特判一下就好了

$p_{now}=0$的时候我们发现$f_{i,j}=f_{i-1,j-1}$，也就是说最后一个人无论如何是不会死的，那么$f_{i-1,j}=f_{i,j+1}$

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

namespace io {

const int BUFSIZE = 1 << 20;
char ibuf[BUFSIZE], *is = ibuf, *it = ibuf;
char obuf[BUFSIZE], *os = obuf, *ot = obuf + BUFSIZE - 1;

if (is == it)
it = (is = ibuf) + fread(ibuf, 1, BUFSIZE, stdin);
return *is++;
}

int x = 0, f = 1;
while (!isdigit(c)) {
if (c == '-') f = -1;
}
while (isdigit(c)) x = x * 10 + c - '0', c = read_char();
return x * f;
}

ll x = 0, f = 1;
while (!isdigit(c)) {
if (c == '-') f = -1;
}
while (isdigit(c)) x = x * 10 + c - '0', c = read_char();
return x * f;
}

while (!isspace(c)) *s++ = c, c = read_char();
*s = 0;
}

void flush() {
fwrite(obuf, 1, os - obuf, stdout);
os = obuf;
}

void print_char(char c) {
*os++ = c;
if (os == ot) flush();
}

void print_int(int x) {
static char q[20];
if (!x) print_char('0');
else {
if (x < 0) print_char('-'), x = -x;
int top = 0;
while (x) q[top++] = x % 10 + '0', x /= 10;
while (top--) print_char(q[top]);
}
}

void print_ll(ll x) {
static char q[20];
if (!x) print_char('0');
else {
if (x < 0) print_char('-'), x = -x;
int top = 0;
while (x) q[top++] = x % 10 + '0', x /= 10;
while (top--) print_char(q[top]);
}
}

struct flusher_t {
~flusher_t() {
flush();
}
} flusher;

};
using namespace io;

const int Mod = 998244353;
const int N = 210;

int add(int a, int b) {
return (a += b) >= Mod ? a - Mod : a;
}

int sub(int a, int b) {
return (a -= b) < 0 ? a + Mod : a;
}

int mul(int a, int b) {
return 1ll * a * b % Mod;
}

int fast_pow(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res = mul(res, a);
b >>= 1;
a = mul(a, a);
}
return res;
}

int n, q, m[N], inv[N];
int c[N], res[N];
int p[N][N], f[N][N], g[N][N];

//p[i][j] 第i个人 还有j点血的概率
//f[i][j] 前i个人还有j个人活下来的概率
//g[i][j] 除了第i个人 还有j个人活下来的概率

int main() {
inv[0] = 1;
for (int i = 1; i <= n; ++i) {
p[i][m[i]] = 1;
inv[i] = fast_pow(i, Mod - 2);
}
while (q--) {
if (!op) {
int k = mul(fast_pow(p2, Mod - 2), p1);
for (int i = 1; i <= m[x]; ++i) {
p[x][i] = add(mul(p[x][i + 1], k), mul(p[x][i], sub(1, k)));
}
} else {
for (int i = 1; i <= num; ++i) {
}
f[0][0] = 1;
for (int i = 1; i <= num; ++i) {
f[i][0] = mul(f[i - 1][0], p[c[i]][0]);
for (int j = 1; j <= i; ++j) {
f[i][j] = add(mul(f[i - 1][j - 1], sub(1, p[c[i]][0])), mul(f[i - 1][j], p[c[i]][0]));
}
}
for (int i = 1; i <= num; ++i) {
int invp = fast_pow(p[c[i]][0], Mod - 2);
if (!p[c[i]][0]) g[i][0] = f[num][1];
else g[i][0] = mul(f[num][0], invp); //**
for (int j = 1; j < num; ++j) {
if (!p[c[i]][0]) g[i][j] = f[num][j + 1];
else g[i][j] = mul(invp, sub(f[num][j], mul(g[i][j - 1], sub(1, p[c[i]][0]))));
}
}
for (int i = 1; i <= num; ++i) {
res[i] = 0;
for (int j = 0; j < num; ++j) {
res[i] = add(res[i], mul(inv[j + 1], g[i][j]));
}
res[i] = mul(res[i], sub(1, p[c[i]][0]));
print_int(res[i]), print_char(' ');
}
print_char('\n');
}
}
for (int i = 1; i <= n; ++i) {
int cur = 0;
for (int j = 1; j <= m[i]; ++j) {
}