题解

一道神仙的题><

我们毙掉一个人后总的w的和会减少,怎么看怎么像指数算法

然而,我们可以容斥……

设\(\sum_{i = 1}^{n} w_{i} = Sum\)

我们把问题转化一下,就是一个猎人死掉之后,并不认为他死掉了,他还活着,只是毙掉他的时候,再毙一次

很容易发现这是个正无穷的递归……但是……这是对的!

例如下一个毙掉\(i\)的概率,死掉的人的w和是\(B\),则

\(P = \frac{B}{A}P + \frac{w_{i}}{A}\)

我们当成一元一次方程解,很容易发现

\(P = \frac{w_{i}}{A - B}\)

很容易发现这个式子是对的

然后我们选出来一堆人,设这些人w的和为\(S\)

我们要求的是这些人在1号人以后毙掉的概率,剩下人随意

\(P = \sum_{i = 0}^{+\infty}(1 - \frac{S + w_{1}}{A})^{i} \frac{w_{1}}{A}\)

就是我们从除了第一个人和S这些人里找人毙掉,反正我们可以反复毙掉一个人,最后再乘上第一个人被毙掉的概率

这个式子可以写成这样

\(P = (1 - \frac{S + w_{1}}{A})P + \frac{w_{1}}{A}\)

解出来

\(P = \frac{w_{1}}{S + w_{1}}\)

……

好吧

然后我们显然容斥系数是(-1)的人数次幂,对于加入一个人,对系数的贡献是-1

我们可以用S进行分类,可以背包求出每个S的系数

然后发现这可以用生成函数进行优化\(\prod_{i = 2}^{n} (1 - x^{w_{i}})\)

很明显的分治NTT

代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#define enter putchar('\n')
#define space putchar(' ')
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define pii pair<int,int>
#define eps 1e-7
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
typedef vector<int> poly; template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
} const int MOD = 998244353,MAXL = 1 << 18;
int W[MAXL + 5],N,val[MAXN],sum;
poly ans;
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int fpow(int x,int c) {
int res = 1,t = x;
while(c) {
if(c & 1) res = mul(res,t);
t = mul(t,t);
c >>= 1;
}
return res;
}
void NTT(poly &f,int L,int on) {
f.resize(L);
for(int i = 1 ,j = L / 2 ; i < L - 1 ; ++i) {
if(i < j) swap(f[i],f[j]);
int k = L / 2;
while(j >= k) {
j -= k;
k >>= 1;
}
j += k;
}
for(int h = 2 ; h <= L ; h <<= 1) {
int wn = W[(MAXL + on * MAXL / h) % MAXL];
for(int k = 0 ; k < L ; k += h) {
int w = 1;
for(int j = k ; j < k + h / 2 ; ++j) {
int u = f[j],t = mul(f[j + h / 2],w);
f[j] = inc(u,t);
f[j + h / 2] = inc(u,MOD - t);
w = mul(w,wn);
}
}
}
if(on == -1) {
int InvL = fpow(L,MOD - 2);
for(int i = 0 ; i < L ; ++i) f[i] = mul(f[i],InvL);
}
}
poly operator * (poly a,poly b) {
int t = a.size() + b.size();
int l = 1;
while(l <= t) l <<= 1;
NTT(a,l,1);NTT(b,l,1);
poly c;c.clear();c.resize(l);
for(int i = 0 ; i < l ; ++i) {
c[i] = mul(a[i],b[i]);
}
NTT(c,l,-1);
for(int i = l - 1 ; i >= 0 ; --i) {
if(c[i] == 0) c.pop_back();
else break;
}
return c;
}
void Init() {
srand(20020421);
W[0] = 1;W[1] = fpow(3,(MOD - 1) / MAXL);
for(int i = 2 ; i < MAXL ; ++i) W[i] = mul(W[i - 1],W[1]);
read(N);
for(int i = 1 ; i <= N ; ++i) {read(val[i]);sum += val[i];}
random_shuffle(val + 2,val + N + 1);
}
poly Solve(int l,int r) {
if(l == r) {
poly g;
g.clear();
g.resize(val[l] + 1);
g[val[l]] = MOD - 1;g[0] = 1;
return g;
}
int mid = (l + r) >> 1;
return Solve(l,mid) * Solve(mid + 1,r);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
if(N == 1) {
puts("1");
return 0;
}
ans = Solve(2,N);
int res = 0;
ans.resize(sum);
for(int i = 0 ; i <= sum ; ++i) {
res = inc(res,mul(ans[i],mul(val[1],fpow(val[1] + i,MOD - 2))));
}
out(res);enter;
return 0;
}

【LOJ】#2541. 「PKUWC2018」猎人杀的更多相关文章

  1. LOJ #2541「PKUWC2018」猎人杀

    这样$ PKUWC$就只差一道斗地主了 假装补题补完了吧..... 这题还是挺巧妙的啊...... LOJ # 2541 题意 每个人有一个嘲讽值$a_i$,每次杀死一个人,杀死某人的概率为$ \fr ...

  2. LOJ 2541 「PKUWC2018」猎人杀——思路+概率+容斥+分治

    题目:https://loj.ac/problem/2541 看了题解才会……有三点很巧妙. 1.分母如果变动,就很不好.所以考虑把操作改成 “已经选过的人仍然按 \( w_i \) 的概率被选,但是 ...

  3. loj#2541. 「PKUWC2018」猎人杀

    传送门 思路太清奇了-- 考虑容斥,即枚举至少有哪几个是在\(1\)号之后被杀的.设\(A=\sum_{i=1}^nw_i\),\(S\)为那几个在\(1\)号之后被杀的人的\(w\)之和.关于杀了人 ...

  4. 「PKUWC2018」猎人杀

    「PKUWC2018」猎人杀 解题思路 首先有一个很妙的结论是问题可以转化为已经死掉的猎人继续算在概率里面,每一轮一直开枪直到射死一个之前没死的猎人为止. 证明,设所有猎人的概率之和为 \(W\) , ...

  5. [LOJ2541]「PKUWC2018」猎人杀

    loj description 有\(n\)个猎人,每个猎人有一个仇恨度\(w_i\),每个猎人死后会开一枪打死一个还活着的猎人,打中每个猎人的概率与他的仇恨度成正比. 现在你开了第一枪,打死每个猎人 ...

  6. loj2541 「PKUWC2018」猎人杀 【容斥 + 分治NTT】

    题目链接 loj2541 题解 思路很妙啊, 人傻想不到啊 觉得十分难求,考虑容斥 由于\(1\)号可能不是最后一个被杀的,我们容斥一下\(1\)号之后至少有几个没被杀 我们令\(A = \sum\l ...

  7. LOJ2541. 「PKUWC2018」猎人杀 [概率,分治NTT]

    传送门 思路 好一个神仙题qwq 首先,发现由于一个人死之后分母会变,非常麻烦,考虑用某种方法定住分母. 我们稍微改一改游戏规则:一个人被打死时只打个标记,并不移走,也就是说可以被打多次但只算一次.容 ...

  8. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

  9. loj#2537. 「PKUWC2018」Minimax

    题目链接 loj#2537. 「PKUWC2018」Minimax 题解 设\(f_{u,i}\)表示选取i的概率,l为u的左子节点,r为u的子节点 $f_{u,i} = f_{l,i}(p \sum ...

随机推荐

  1. Java基础-方法(method)的应用

    Java基础-方法(method)的应用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 方法就是定义在类中,具有特定功能的一段小程序,方法也称为函数(function),方法可以接 ...

  2. PHP数组的遍历

    对于012345...这样的数组可以用for进行遍历 $arr=array('a','b','c','d','e'); for($key=0;$key<count($arr);$key++){ ...

  3. bzoj千题计划130:bzoj1305: [CQOI2009]dance跳舞

    http://www.lydsy.com/JudgeOnline/problem.php?id=1305 每个人拆为喜欢(yes)和不喜欢(no)两个点 二分答案 1.每两个人之间只能跳一次 喜欢则 ...

  4. 2017 清北济南考前刷题Day 5 afternoon

    期望得分:100+100+30=230 实际得分:0+0+0=30 T1 直接模拟 #include<cstdio> #include<iostream> using name ...

  5. Linux安装配置SVN服务器

    1. 安装SVN服务器: 检查是否已安装 # rpm -qa subversion 安装SVN服务器 # yum install httpd httpd-devel subversion mod_da ...

  6. 11 Facts about Data Science that you must know

    11 Facts about Data Science that you must know Statistics, Machine Learning, Data Science, or Analyt ...

  7. 【AtCoder Grand Contest 001F】Wide Swap [线段树][拓扑]

    Wide Swap Time Limit: 50 Sec  Memory Limit: 512 MB Description Input Output Sample Input 8 3 4 5 7 8 ...

  8. POJ 2230 Watchcow && USACO Watchcow 2005 January Silver (欧拉回路)

    Description Bessie's been appointed the new watch-cow for the farm. Every night, it's her job to wal ...

  9. Android笔记之开机自启

    有时候需要应用具有开机自启的能力,或者更常见的场景是开机时悄悄在后台启动一个Service. 关键点: 1. Android系统在开机的时候会发送一条广播消息,只需要接收这条广播消息即可,不过需要注意 ...

  10. vue中使用localStorage存储信息

    一 什么是localStorage 对浏览器来说,使用 Web Storage 存储键值对比存储 Cookie 方式更直观,而且容量更大,它包含两种:localStorage 和 sessionSto ...