# [做题记录] ZJOI2019 开关 题解

## ZJOI2019 开关

### 题意

$$n$$ 个开关， 初始的时候都是 $$0$$, 给出一个状态 $$s$$ ， 每次以 $$\frac{p_i}{\sum_{j = 1}^np_j}$$ 的概率按下一个开关 $$i$$ 期望多少次以后可以第一次达到这个状态。
$$n \leq 100, \sum p_i \leq 5\times 10^4$$

### 题解

$$a_i = \frac{p_i}{\sum_{i = 1}^np_j}, m = \sum_{i = 1}^n p_i$$

$\hat{F}(x) = \prod_{i = 1}^n \frac{e^{a_ix}+ (-1) ^{s_i}e^{-a_ix}}{2}$

$\hat{G}(x) = \prod_{i = 1}^n \frac{e^{a_ix}+ e^{-a_ix}}{2}$

$$F$$ 为例考虑对其动手动脚。

$\hat{F} = \sum_jf_je^{\frac{j}{m}x}$

$F = \sum_jf_j\frac{m}{m - jx}$

$$P(x) = F(x)(1 - x), Q(x) = G(x)(1 - x)$$

$$Q, Q'$$ 可以同理得出。

#include <bits/stdc++.h>

const int P = 998244353;
inline int mod(int x) { return x + (x >> 31 & P); }
inline void pls(int &x, int y) { x = mod(x + y - P); }
inline void sub(int &x, int y) { x = mod(x - y); }
inline int power(int x, int k) {
int res = 1; if(x < 0) x += P;
while(k) {
if(k & 1) res = 1ll * res * x % P;
x = 1ll * x * x % P; k >>= 1;
}
return res;
}

const int N = 100 + 5, M = 5e4 + 5;

int n, s[N], p[N], m;
int pool[3][M << 1];
int *F = pool[0] + M, *G = pool[1] + M, *t = pool[2] + M;

int main() {
std :: ios :: sync_with_stdio(false);
std :: cin.tie(0); std :: cout.tie(0);
std :: cin >> n;
for(int i = 1; i <= n; i ++) std :: cin >> s[i];
for(int i = 1; i <= n; i ++) std :: cin >> p[i], m += p[i];
F[0] = 1;
for(int i = 1; i <= n; i ++) {
int sgn = (s[i] == 1 ? P - 1 : 1);
for(int j = - m; j <= m; j ++)
if(F[j])
pls(t[j + p[i]], F[j]), pls(t[j - p[i]], 1ll * F[j] * sgn % P);
for(int j = - m; j <= m; j ++) F[j] = t[j], t[j] = 0;
}
G[0] = 1;
for(int i = 1; i <= n; i ++) {
for(int j = - m; j <= m; j ++)
if(G[j]) pls(t[j + p[i]], G[j]), pls(t[j - p[i]], G[j]);
for(int j = - m; j <= m; j ++) G[j] = t[j], t[j] = 0;
}
int p1 = F[m], p2 = 0, q1 = G[m], q2 = 0;
for(int i = - m; i <= m - 1; i ++)
pls(p2, 1ll * F[i] * m % P * power(i - m, P - 2) % P);
for(int i = - m; i <= m - 1; i ++)
pls(q2, 1ll * G[i] * m % P * power(i - m, P - 2) % P);
int ans = 1ll * (1ll * p2 * q1 % P - 1ll * p1 * q2 % P + P) * power(1ll * q1 * q1 % P, P - 2) % P;
std :: cout << ans << std :: endl;
return 0;
}
posted @ 2022-01-23 23:58  HN-wrp  阅读(53)  评论(0编辑  收藏  举报