• 题解

    • 题目中的选择条件等价于正常选择所有猎人,而如果选到已经出局的猎人就继续选;
    • 这两种选法是一样的因为(设$W=\sum_{i=1}^{n}w_{i}$ , $X$为已经出局的猎人的$w$之和):
    • $P_{i} = \sum_{i=0}^{ \infty } {(\frac{X}{W})}^i \frac{w_{i}}{W}$
    • $= \frac{w_{i}}{W} \sum_{i=0}^{ \infty } {(\frac{X}{W})}^i$
    • $ = \frac{w_{i}}{W} \frac{1}{1-\frac{X}{W}}$
    • $ = \frac{w_{i}}{W-X} $
    • 考虑枚举强制$S$集合$(1 \notin S)$中的人在1之后出局,设$X(S) = \sum_{i=2}^{n} [i \in S]w_{i}$;
    • $ans = \sum_{S} {(-1)}^{|S|}  \sum_{i=0}^{ \infty }  (1-\frac{w_{1}+X(S)}{W})^i  \frac{w_{1}}{W} $
    • $ans  = \sum_{S} {(-1)}^{|S|} \frac{w_{1}}{w_{1}+X(S)} $
    • 考虑求这个式子:
    • $ans = \sum_{i=0}^{W} \frac{w_{1}}{w_{1}+i} \sum_{S} [X(S)==i] (-1)^{|S|}$
    • 用生成函数$\Pi_{i=2}^{n} (1-x^{w_{i}})$处理处后面的部分即可;
    • 时间复杂度:$O(Wlog^2 \ W)$
 #include<bits/stdc++.h>
#define mod 998244353
using namespace std;
const int N=,M=;
int n,m,w[N],f[M][N],mx[M],L,len,sz,Wn[M][N],rev[N];
char gc(){
static char*p1,*p2,s[];
if(p1==p2)p2=(p1=s)+fread(s,,,stdin);
return(p1==p2)?EOF:*p1++;
}
int rd(){
int x=;char c=gc();
while(c<''||c>'')c=gc();
while(c>=''&&c<='')x=(x<<)+(x<<)+c-'',c=gc();
return x;
}
int pw(int x,int y){
int re=;
for(;y;y>>=,x=1ll*x*x%mod)if(y&)re=1ll*re*x%mod;
return re;
}
void ntt(int*a,int f){
for(int i=;i<len;++i)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int i=;i<len;i<<=){
int wn=Wn[!~f][i<<];
for(int j=;j<len;j+=i<<){
int w=;
for(int k=;k<i;++k,w=1ll*wn*w%mod){
int x=a[j+k],y=1ll*w*a[j+k+i]%mod;
a[j+k]=(x+y)%mod,a[j+k+i]=(x-y+mod)%mod;
}
}
}
if(!~f){
int iv=pw(len,mod-);
for(int i=;i<len;++i)a[i]=1ll*a[i]*iv%mod;
}
}
void solve(int l,int r){
if(l==r){
mx[++sz]=w[l];
f[sz][]=;f[sz][w[l]]=mod-;
for(int i=;i<w[l];++i)f[sz][i]=;
return ;
}
int mid=(l+r)>>;
solve(l,mid),solve(mid+,r);
int a=sz-,b=sz;
m=mx[a]+mx[b];
for(L=,len=;len<=m;len<<=,L++);
for(int i=;i<len;++i)rev[i]=(rev[i>>]>>)|((i&)<<(L-));
for(int i=mx[a]+;i<len;++i)f[a][i]=;
for(int i=mx[b]+;i<len;++i)f[b][i]=;
ntt(f[a],);ntt(f[b],);
for(int i=;i<len;++i)f[a][i]=1ll*f[a][i]*f[b][i]%mod;
ntt(f[a],-);
mx[--sz]=m;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("loj2541.in","r",stdin);
freopen("loj2541.out","w",stdout);
#endif
n=rd();
for(int i=;i<=n;++i)w[i]=rd();
for(int i=<<;i;i>>=){
Wn[][i]=pw(,(mod-)/i);
Wn[][i]=pw(Wn[][i],mod-);
}
solve(,n);
int ans=;
for(int i=;i<=mx[];++i){
ans=(ans + 1ll*f[][i]*w[]%mod*pw(i+w[],mod-)%mod)%mod;
}
cout<<(ans+mod)%mod<<endl;
return ;
}

loj2541【PKUWC2018】猎人杀的更多相关文章

  1. LOJ2541 PKUWC2018猎人杀(概率期望+容斥原理+生成函数+分治NTT)

    考虑容斥,枚举一个子集S在1号猎人之后死.显然这个概率是w1/(Σwi+w1) (i∈S).于是我们统计出各种子集和的系数即可,造出一堆形如(-xwi+1)的生成函数,分治NTT卷起来就可以了. #i ...

  2. LOJ2541 PKUWC2018 猎人杀 期望、容斥、生成函数、分治

    传送门 首先,每一次有一个猎人死亡之后\(\sum w\)会变化,计算起来很麻烦,所以考虑在某一个猎人死亡之后给其打上标记,仍然计算他的\(w\),只是如果打中了一个打上了标记的人就重新选择.这样对应 ...

  3. [LOJ2541][PKUWC2018]猎人杀(容斥+分治+FFT)

    https://blog.csdn.net/Maxwei_wzj/article/details/80714129 n个二项式相乘可以用分治+FFT的方法,使用空间回收可以只开log个数组. #inc ...

  4. [LOJ2541] [PKUWC2018] 猎人杀

    题目链接 LOJ:https://loj.ac/problem/2541 Solution 很巧妙的思路. 注意到运行的过程中概率的分母在不停的变化,这样会让我们很不好算,我们考虑这样转化:假设所有人 ...

  5. [PKUWC2018]猎人杀

    题解 感觉是一道神题,想不出来 问最后\(1\)号猎人存活的概率 发现根本没法记录状态 每次转移的分母也都不一样 可以考虑这样一件事情: 如果一个人被打中了 那么不急于从所有人中将ta删除,而是给ta ...

  6. 题解-PKUWC2018 猎人杀

    Problem loj2541 题意概要:给定 \(n\) 个人的倒霉度 \(\{w_i\}\),每回合会有一个人死亡,每个人这回合死亡的概率为 自己的倒霉度/目前所有存活玩家的倒霉度之和,求第 \( ...

  7. 洛谷 P5644 - [PKUWC2018]猎人杀(分治+NTT)

    题面传送门 很久之前(2020 年)就听说过这题了,这么经典的题怎么能只听说而亲自做一遍呢 首先注意到每次开枪打死一个猎人之后,打死其他猎人概率的分母就会发生变化,这将使我们维护起来非常棘手,因此我们 ...

  8. 【洛谷5644】[PKUWC2018] 猎人杀(容斥+生成函数+分治NTT)

    点此看题面 大致题意: 有\(n\)个人相互开枪,每个人有一个仇恨度\(a_i\),每个人死后会开枪再打死另一个还活着的人,且第一枪由你打响.设当前剩余人仇恨度总和为\(k\),则每个人被打中的概率为 ...

  9. 【LOJ2541】【PKUWC2018】猎人杀(容斥,FFT)

    [LOJ2541][PKUWC2018]猎人杀(容斥,FFT) 题面 LOJ 题解 这题好神仙啊. 直接考虑概率很麻烦,因为分母总是在变化. 但是,如果一个人死亡之后,我们不让他离场,假装给他打一个标 ...

  10. 「PKUWC2018」猎人杀

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

随机推荐

  1. ubuntu下Open vSwitch安装

    ubuntu下Open vSwitch安装 有关Open vSwitch的安装,网上有各种的教程资料,但一些已经过时,按照网上的教程,花费了大量时间,都没能安装成功.于是,通过查阅官方安装教程以及综合 ...

  2. 深度学习中数据的augmentation

    为了提高模型的泛化能力,同时也为了增大数据集,我们往往需要对数据进行augmentation,在这篇博客中,将总结一下可以对数据进行的augmentation. 1.颜色数据增强,对图像亮度.饱和度. ...

  3. Qt 5.x 开发技巧

    出现unresolved external symbol "public: __thiscall Dialog::Dialog(class QWidget *) 或类似不太合理的错误时,可以 ...

  4. ossec安装

    安装 安装要求 对于Unix系统来说,OSSEC只需要GNU的make.gcc和libc.推荐使用OpenSSL,但仅属于一个可选项.而且,通常您只需在一个系统上做编译操作,然后将二进制程序复制到其他 ...

  5. shell--read命令

    read命令 -p(提示语句) -n(字符个数) -t(等待时间) -s(不回显) 1.基本读取read命令接收标准输入(键盘)的输入,或其他文件描述符的输入(后面在说).得到输入后,read命令将数 ...

  6. 对于新手来说,Python 中有哪些难以理解的概念?

    老手都是从新手一路过来的,提起Python中难以理解的概念,可能很多人对于Python变量赋值的机制有些疑惑,不过对于习惯于求根究底的程序员,只有深入理解了某个事物本质,掌握了它的客观规律,才能得心应 ...

  7. 2017年第八届蓝桥杯【C++省赛B组】

    1.标题: 购物单 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都是有 ...

  8. n以内的1的个数

    import java.util.Scanner; public class main { /** * @param args */ public static void main(String[] ...

  9. Task 10 统计从1到某个整数之间出现的1的次数

    任务:给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数. 要求: 写一个函数 f(N) ,返回1 到 N 之间出现的 “1”的个数.例如 f(12) = 5. 在3 ...

  10. sprint初步计划(第一天)

    一.现状 小组成员初步了解四则运算程序编写大概内容,进行简单的讨论.只知道大概的流程,实际还没做出.现在明确目标是把我们写Java的四则运算变成一个手机APP,关于手机ap,我们还不是很了解,所以需要 ...