0
点赞
收藏
分享

微信扫一扫

「ZJOI2019」开关 (生成函数)(概率)

火热如冰 2022-07-12 阅读 58

​​传送门​​

一道毒瘤的生成函数推导题
一开始发现概率 「ZJOI2019」开关 (生成函数)(概率)_生成函数 加一个高斯消元可以过 「ZJOI2019」开关 (生成函数)(概率)_生成函数_02,然后一直在想 「ZJOI2019」开关 (生成函数)(概率)_生成函数……

  • 题解:
    我们令成功了但不结束的概率指数生成函数为「ZJOI2019」开关 (生成函数)(概率)_生成函数_04,直接上单位根反演
    「ZJOI2019」开关 (生成函数)(概率)_生成函数_05
    「ZJOI2019」开关 (生成函数)(概率)_生成函数_06
    考虑让成功过后停下来,我们构造走「ZJOI2019」开关 (生成函数)(概率)_git_07步回到本身状态的概率指数生成函数「ZJOI2019」开关 (生成函数)(概率)_生成函数_08,那么
    「ZJOI2019」开关 (生成函数)(概率)_i++_09
    令走「ZJOI2019」开关 (生成函数)(概率)_git_07步成功的概率的普通生成从函数为「ZJOI2019」开关 (生成函数)(概率)_生成函数_11「ZJOI2019」开关 (生成函数)(概率)_git_12转为普通生成函数为「ZJOI2019」开关 (生成函数)(概率)_i++_13
    那么有
    「ZJOI2019」开关 (生成函数)(概率)_i++_14
    注意到答案求的就是
    「ZJOI2019」开关 (生成函数)(概率)_i++_15
    下面考虑分别求出「ZJOI2019」开关 (生成函数)(概率)_i++_16
    「ZJOI2019」开关 (生成函数)(概率)_git_17
    「ZJOI2019」开关 (生成函数)(概率)_git_18
    考虑这玩意在 1 处不收敛,将「ZJOI2019」开关 (生成函数)(概率)_生成函数_19同乘「ZJOI2019」开关 (生成函数)(概率)_git_20
    那么
    「ZJOI2019」开关 (生成函数)(概率)_git_21
    只在「ZJOI2019」开关 (生成函数)(概率)_git_22处有值
    「ZJOI2019」开关 (生成函数)(概率)_生成函数_23
    只在「ZJOI2019」开关 (生成函数)(概率)_git_22「ZJOI2019」开关 (生成函数)(概率)_i++_25处有值,于是可以「ZJOI2019」开关 (生成函数)(概率)_生成函数_26
    处理系数「ZJOI2019」开关 (生成函数)(概率)_i++_27就是个背包,复杂度「ZJOI2019」开关 (生成函数)(概率)_生成函数_28
#include<bits/stdc++.h>
#define cs const
using namespace std;
int read(){
int cnt = 0, f = 1; char ch = 0;
while(!isdigit(ch)){ ch = getchar(); if(ch == '-') f = -1; }
while(isdigit(ch)) cnt = cnt*10 + (ch-'0'), ch = getchar();
return cnt * f;
}
cs int N = 105, M = 1e5 + 50;
cs int Mod = 998244353;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
int dec(int a, int b){ return a - b < 0 ? a - b + Mod : a - b; }
int ksm(int a, int b){ int ans=1; for(;b;b>>=1,a=mul(a,a)) if(b&1) ans=mul(ans,a); return ans; }
void Add(int &a, int b){ a = add(a, b); }
void Dec(int &a, int b){ a = dec(a, b); }
void Mul(int &a, int b){ a = mul(a, b); }
int fix(int a){ return a < 0 ? a + Mod : a; }
int n, s[N], p[N], S, iS, f[M], g[M];
int func(int *f){
int ans = f[S+S];
for(int i = -S; i < S; i++) Mul(ans, dec(1,mul(fix(i),iS)));
return ans;
}
int deriv(int *f){
static int coef[M];
int sum = 1, ans = 0;
for(int i = -S; i < S; i++) Mul(sum, dec(1,mul(fix(i),iS)));
for(int i = -S; i < S; i++) coef[i+S] = mul(sum, ksm(dec(1,mul(fix(i),iS)),Mod-2));
sum = 0;
for(int i = -S; i < S; i++) Add(sum, mul(mul(fix(i),iS), coef[i+S]));
Add(ans, mul(sum, f[S+S]));
for(int i = -S; i < S; i++) Dec(ans, mul(f[i+S], coef[i+S]));
return ans;
}
int main(){
n = read();
for(int i = 1; i <= n; i++) s[i] = read();
for(int i = 1; i <= n; i++) p[i] = read(), S += p[i];
iS = ksm(S, Mod-2);
f[S] = g[S] = 1;
for(int i = 1, now = 0; i <= n; i++){
static int tf[M], tg[M];
memset(tf, 0, sizeof(tf));
memset(tg, 0, sizeof(tg));
for(int j = -now; j <= now; j++){
if(s[i] == 0) Add(tf[j + S - p[i]], f[j + S]);
else Dec(tf[j + S - p[i]], f[j + S]);
Add(tf[j + S + p[i]], f[j + S]);
Add(tg[j + S + p[i]], g[j + S]);
Add(tg[j + S - p[i]], g[j + S]);
}
memcpy(f, tf, sizeof(tf));
memcpy(g, tg, sizeof(tg)); now += p[i];
}
int fg = func(g), res = mul(fg, deriv(f));
Dec(res, mul(func(f), deriv(g)));
cout << mul(res, ksm(mul(fg,fg), Mod-2)); return 0;
}


举报

相关推荐

0 条评论