1. 程式人生 > >【雜題】[LibreOJ 2541] 【PKUWC2018】獵人殺【生成函式】【概率與期望】

【雜題】[LibreOJ 2541] 【PKUWC2018】獵人殺【生成函式】【概率與期望】

Description

獵人殺是一款風靡一時的遊戲“狼人殺”的民間版本,他的規則是這樣的:
一開始有 n個獵人,第 i 個獵人有仇恨度 wi。每個獵人只有一個固定的技能:死亡後必須開一槍,且被射中的人也會死亡。
然而向誰開槍也是有講究的,假設當前還活著的獵人有 [ i 1 . .

. i m ] [i_1...i_m] ,那麼有 w i
k j = 1 m
w i j
w_{i_k}\over \sum\limits_{j=1}^{m} w_{i_j}
的概率是向獵人 i k i_k 開槍
一開始第一槍由你打響,目標的選擇方法和獵人一樣(即有 w i j = 1 m w j w_{i}\over \sum\limits_{j=1}^{m} w_{j} 的概率射中第i個獵人)。由於開槍導致的連鎖反應,所有獵人最終都會死亡,現在1號獵人想知道它是最後一個死的的概率。
對998244353取模
w i > 0 , w i 100000 w_i>0,\sum w_i\leq 100000

Solution

首先有結論,我們假設可以對已經死亡的獵人開槍,對已經死亡獵人開槍之後繼續開槍,那麼問題是等價的。

這樣就好做不少,因為每個人中槍的概率就固定了。
根據這個結論,我們來推一波式子。

我們可以將整個開槍過程看做是一個序列,每個數可以出現多次,每個數出現有概率,題目問的是1出現時其他所有數都已經出現過的概率。

考慮指數型生成函式,設 t = w k t=\sum w_k ,容易得出除1號外i號獵人的EGF是 j > 0 w i j x j t j i ! = e w i x t 1 \sum\limits_{j>0}{w_i^jx^j\over t^ji!}=e^{w_ix\over t}-1

那麼將這些獵人拼接,總的式子就是 k = 2 n ( e w k x t 1 ) \prod\limits_{k=2}^{n}(e^{w_kx\over t}-1)

假設有3個獵人,2,3號獵人拼在一起就是 e ( w 2 + w 3 ) x t e w 2 x t e w 3 x t + 1 e^{(w_2+w_3)x\over t}-e^{w_2x\over t}-e^{w_3x\over t}+1

對於每個EGF,它對總概率的貢獻就是其係數之和
對於 e p x e^{px} ,將其係數求和(不考慮階乘),就是等比數列求和的形式,可以得出和就是 1 1 p 1\over 1-p

那麼對於上面的式子,一樣計算和,然後加到一起,最後再乘上 w 1 / t w_1/t (最後一次要選上1號)

現在問題的關鍵就是要算上面的乘積的每一項 e p x p [ 0 , t ] e^{px},p\in[0,t] 的係數

我們可以把每個 e p x e^{px} 也看做多項式的一項,因為同是指數相加,可以構造多項式 x w k t 1 x^{w_k\over t}-1 ,那麼 k = 2 n ( x w k t 1 ) \prod\limits_{k=2}^{n}(x^{w_k\over t}-1)
的每一項 x p x^{p} 前的係數就是原式中每一個 e p x e^{px} 的係數
可以先不看t,用分治NTT做,最後再算上。

總複雜度 O ( n log 2 n ) O(n\log^2 n)

Code

#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
#define M 262144
#define L 18
#define mo 998244353
#define LL long long
#define N 100005
using namespace std;
LL wi[M+1],wg[M+1],a[M+1],b[M+1],c[M+1],ny,w[N];
int a1[N],bit[M+1],sz[N],n1,n,sm[N