\(n\) 種卡,每種有權值 \(w_i\) ,\(w_i\) 以 \(p_\) 的概率取 \(j\) ( \(j =1,2,3\) )
不斷抽卡,抽到卡 \(i\) 的概率是 \(\frac^n w_j}\)
設 \(t_i\) 表示第一次抽到 \(i\) 的時間
給定 \(n-1\) 個限制 \((u_i,v_i)\) ,要求 \(t_,以所有限制做邊可形成一棵 \(n\) 個節點的樹
求滿足所有限制的概率
\(n \leq 10^6\)
乍一看不好下手,於是考慮子樹 \(dp\)
假設是外向樹,且已知 \(w_i\) ,則中獎概率為 \(\prod\frac\)
則總中獎概率為 \(\sum [(\prod\limits_^n p_)\times \prod\limits_^n \frac]\)
用 \(dp\) 計算,設以 \(i\) 為根的子樹,\(size_i\) 為 \(s\) 的情況下,整個子樹的中獎概率為 \(f[u][s]\)
當 \(u\) 僅有自己乙個點時, \(f[u][s]=p_=\frac}+a_+a_}\)
邊 \((u,v)\) 將子節點 \(v\) 的 \(dp\) 值更新 \(u\) (\(f'[u][s]\) 表示更新前的),\(f[u][s]+=\sum f[v][i]\times f'[u][s-i]\times \frac\)
進行樹形揹包 \(dp\) 就可以了,複雜度 \(o(n^2)\)
然而上面做法只針對外向樹,如果有從兒子指向父親的反向邊怎麼辦呢?
容斥!\(ans=\sum (-1)^i \times 至少 i 條反向邊不合法\)
直接在整棵樹中列舉哪些反向邊不合法的複雜度過高,考慮仍在樹形 \(dp\) 中容斥
考慮連線 \(u\) 與子節點 \(v\) 的邊 \((u,v)\)
1.如果它原本是正向邊,則轉移方式不變:\(f[u][s]+=\sum f[v][i]\times f'[u][s-i]\times \frac\)
2.如果它原本是反向邊,則討論它在不在「至少 \(i\) 條反向邊不合法」中
咋一看複雜的問題,可先從小規模問題入手分析(如樹形結構的問題考慮子樹)
樹上揹包的寫法,可以考慮是對每條邊 \((u,v)\) ,用 \(v\) 更新 \(u\) 的 \(dp\) 值。
取模檢查 \(1ll*\) 與 \(\%p\)
#include#include#include#define p 998244353
using namespace std;
int read()
const int n = 1005;
int n,a[n][4];
struct nodepool[n*2],*h[n];
int cnt;
void addedge(int u,int v)
int pow_mod(int x,int y)
return ret;
}int plus(int x,int y)
int inv[n*3];
int f[n][n*3],sz[n],g[n*3];
void dfs(int u,int fa)
else
}}int main()
int u,v;
for(int i=1;iinv[1]=1;
for(int i=2;i<=n*3;i++) inv[i]=p-1ll*(p/i)*inv[p%i]%p;
dfs(1,0);
int ans=0;
for(int i=1;i<=n*3;i++) ans=plus(ans,f[1][i]);
printf("%d\n",ans);
return 0;
}
CTS2019 氪金手遊
解題思路 考場上想出了外向樹的做法,居然沒意識到反向邊可以容斥,其實外向樹會做的話這個題差不多就做完了。令 dp u i 表示單獨考慮 u 節點所在子樹,子樹內 sum w i 的合法概率,可以簡單證明子樹外的選取是不影響子樹內的答案的,所以可以這樣表示。證明 我們只考慮子樹內的第乙個選出根節點 u...
p5405 CTS2019 氪金手遊
題目大意 題意狗屁不通 看毛子語都比看這個題面強 分析 我們假設這棵樹是乙個內向樹 那麼我們可以輕易的得到dp x i 表示x點子樹和為i的期望 轉移只需列舉當前期望大小和子樹期望大小即可 但是由於邊的方向不一定 所以這棵樹上存在反向邊 我們可以容斥有i個邊不合法的情況 因此對於乙個反向邊要麼x點加...
P5405 CTS2019 氪金手遊
這應該是cts2019最簡單的題。lhm 首先假設題目給的是乙個單向的鏈,並且所有 w 都是確定的,那麼顯然第一步一定要選擇鏈的起點,概率為 frac 第二步如果選到起點,就再選一次,因此相當於與起點無關,因此合法概率為 frac 第三步合法概率為 frac 如果給的是乙個外向樹,我們發現兒子與兒子...