好题分享(P5644 [PKUWC2018]猎人杀)
P5644 [PKUWC2018]猎人杀
题目大意
一开始有 n n n个猎人,第 i i i个猎人有仇恨度 w i w_i wi?。每次可以开枪射杀一个活着的猎人。
假设活着的猎人为 i 1 , i 2 , … , i m i_1,i_2,\dots,i_m i1?,i2?,…,im?,则第 i k i_k ik?个猎人被射杀的概率是 w i k ∑ j = 1 m w i j \frac{w_{i_k}}{\sum\limits_{j=1}^mw_{i_j}} j=1∑m?wij??wik???。
求 1 1 1号猎人最后一个被射杀的概率。输出答案对 998244353 998244353 998244353取模。
对于 10 % 10\% 10% 的数据,有 1 ≤ n ≤ 10 1\leq n\leq 10 1≤n≤10
对于 30 % 30\% 30% 的数据,有 1 ≤ n ≤ 20 1\leq n\leq 20 1≤n≤20
对于 50 % 50\% 50% 的数据,有 1 ≤ ∑ i = 1 n w i ≤ 5000 1\leq \sum\limits_{i=1}^{n}w_i\leq 5000 1≤i=1∑n?wi?≤5000
另有 10 % 10\% 10% 的数据,满足 1 ≤ w i ≤ 2 1\leq w_i\leq 2 1≤wi?≤2,且 w 1 = 1 w_1=1 w1?=1
另有 10 % 10\% 10% 的数据,满足 1 ≤ w i ≤ 2 1\leq w_i\leq 2 1≤wi?≤2,且 w 1 = 2 w_1=2 w1?=2
对于 100 % 100\% 100% 的数据,有 w i > 0 w_i>0 wi?>0,且 1 ≤ ∑ i = 1 n w i ≤ 1 0 5 1\leq \sum\limits_{i=1}^{n}w_i \leq 10^5 1≤i=1∑n?wi?≤105
题解
10pts
枚举所有情况并计算概率,时间复杂度为 O ( n ! ) O(n!) O(n!),可以过 1 ≤ n ≤ 10 1\leq n\leq 10 1≤n≤10的部分分。
30pts
在不断射杀的过程中,概率的分母会不断改变。所以,我们可以稍微转化一下题意。
令 s u m = ∑ i = 1 n w i sum=\sum\limits_{i=1}^nw_i sum=i=1∑n?wi?,题意转化为:第 i i i个人被射杀的概率为 w i s u m \dfrac{w_i}{sum} sumwi??,已经被射杀的人仍能继续被射杀。如果打中一个活着的人,那么这个人就死去。
为什么呢?因为在每次射杀的时候,每个活人被射杀的概率都他的仇恨度除以所有活人仇恨度的和。这样相对于原来,多了一个射杀死人的过程,但因为活人最终总会被射杀,所以本质上是一样的。
直接求 1 1 1号最后被射杀的概率比较困难,我们考虑使用容斥。
设在 1 1 1号之后被射杀的人的子集为 S S S的概率为 p ( S ) p(S) p(S),则答案为
a n s = ∑ ( ? 1 ) ∣ S ∣ p ( S ) ans=\sum(-1)^{|S|}p(S) ans=∑(?1)∣S∣p(S)
然后,我们考虑如何求 p ( S ) p(S) p(S)。
设 v ( S ) = ∑ i ∈ S w i v(S)=\sum\limits_{i\in S}w_i v(S)=i∈S∑?wi?。因为在 1 1 1号之后被射杀的人包含 S S S,所以就相当于射杀若干次,每次射杀除了 1 1 1号和集合 S S S之外的人,直到打中 1 1 1号。
p ( S ) = ∑ i = 0 + ∞ ( s u m ? w 1 ? v ( S ) s u m ) i ? w 1 s u m p(S)=\sum\limits_{i=0}^{+\infty}(\dfrac{sum-w_1-v(S)}{sum})^i\cdot\dfrac{w_1}{sum} p(S)=i=0∑+∞?(sumsum?w1??v(S)?)i?sumw1??
接下来求 ∑ i = 0 + ∞ ( s u m ? w 1 ? v ( S ) s u m ) i \sum\limits_{i=0}^{+\infty}(\frac{sum-w_1-v(S)}{sum})^i i=0∑+∞?(sumsum?w1??v(S)?)i。由等比数列求和公式可得
∑ i = 0 + ∞ ( s u m ? w 1 ? v ( S ) s u m ) i = 1 ? ( s u m ? w 1 ? v ( S ) s u m ) + ∞ 1 ? s u m ? w 1 ? v ( S ) s u m = 1 w 1 + v ( S ) s u m = s u m w 1 + v ( S ) \sum\limits_{i=0}^{+\infty}(\frac{sum-w_1-v(S)}{sum})^i=\dfrac{1-(\frac{sum-w_1-v(S)}{sum})^{+\infty}}{1-\frac{sum-w_1-v(S)}{sum}}=\dfrac{1}{\frac{w_1+v(S)}{sum}}=\dfrac{sum}{w_1+v(S)} i=0∑+∞?(sumsum?w1??v(S)?)i=1?sumsum?w1??v(S)?1?(sumsum?w1??v(S)?)+∞?=sumw1?+v(S)?1?=w1?+v(S)sum?
所以
p ( S ) = s u m w 1 + v ( S ) ? w 1 s u m = w 1 w 1 + v ( S ) p(S)=\dfrac{sum}{w_1+v(S)}\cdot \dfrac{w_1}{sum}=\dfrac{w_1}{w_1+v(S)} p(S)=w1?+v(S)sum??sumw1??=w1?+v(S)w1??
那么
a n s = ∑ ( ? 1 ) ∣ S ∣ w 1 w 1 + v ( S ) ans=\sum(-1)^{|S|}\dfrac{w_1}{w_1+v(S)} ans=∑(?1)∣S∣w1?+v(S)w1??
枚举所有 S S S来计算 a n s ans ans,时间复杂度为 O ( 2 n ) O(2^n) O(2n),可以过 1 ≤ n ≤ 20 1\leq n\leq 20 1≤n≤20的部分分。
50pts
我们注意到 ∑ i = 1 n w i \sum\limits_{i=1}^{n}w_i i=1∑n?wi?的范围并不是很大,所以我们可以枚举 v ( S ) v(S) v(S)。
令
g ( i ) = ∑ v ( S ) = i ( ? 1 ) ∣ S ∣ g(i)=\sum\limits_{v(S)=i}(-1)^{|S|} g(i)=v(S)=i∑?(?1)∣S∣
那么
a n s = ∑ i = 0 s u m g ( i ) ? w 1 w 1 + i ans=\sum\limits_{i=0}^{sum}g(i)\cdot\dfrac{w_1}{w_1+i} ans=i=0∑sum?g(i)?w1?+iw1??
于是问题就转化为求 g ( i ) g(i) g(i)了。我们可以用背包来 O ( s u m 2 ) O(sum^2) O(sum2)求出 g ( i ) g(i) g(i),这可以过 1 ≤ ∑ i = 1 n w i ≤ 5000 1\leq \sum\limits_{i=1}^{n}w_i\leq 5000 1≤i=1∑n?wi?≤5000的部分分。
另外20pts
有 20 20 20分是满足 1 ≤ w i ≤ 2 1\leq w_i\leq 2 1≤wi?≤2且确定了 w 1 w_1 w1?是 1 1 1或者是 2 2 2,这部分我不太清楚怎么做,留给大家思考。
100pts
我们考虑如何快速求出 g ( i ) g(i) g(i)。我们发现, g ( i ) g(i) g(i)其实就是 ∏ i = 2 n ( 1 ? x w i ) \prod\limits_{i=2}^n(1-x^{w_i}) i=2∏n?(1?xwi?)的第 i i i次项的系数。
接下来,我们要用 N T T NTT NTT来求 ∏ i = 2 n ( 1 ? x w i ) \prod\limits_{i=2}^n(1-x^{w_i}) i=2∏n?(1?xwi?)。
用分治,求 [ l , r ] [l,r] [l,r]的多项式时,先求出 [ l , m i d ] [l,mid] [l,mid]和 [ m i d + 1 , r ] [mid+1,r] [mid+1,r]的多项式,再将两个多项式相乘即可。
我们把求的过程看作 log ? n \log n logn层,每层的时间复杂度为 O ( s u m log ? s u m ) O(sum\log sum) O(sumlogsum),所以总时间复杂度为 O ( s u m log ? s u m log ? n ) O(sum\log sum\log n) O(sumlogsumlogn),可以看作 O ( n log ? 2 n ) O(n\log^2 n) O(nlog2n)。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!