loj2541【PKUWC2018】猎人杀
题解
- 题目中的选择条件等价于正常选择所有猎人,而如果选到已经出局的猎人就继续选;
- 这两种选法是一样的因为(设$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】猎人杀的更多相关文章
- LOJ2541 PKUWC2018猎人杀(概率期望+容斥原理+生成函数+分治NTT)
考虑容斥,枚举一个子集S在1号猎人之后死.显然这个概率是w1/(Σwi+w1) (i∈S).于是我们统计出各种子集和的系数即可,造出一堆形如(-xwi+1)的生成函数,分治NTT卷起来就可以了. #i ...
- LOJ2541 PKUWC2018 猎人杀 期望、容斥、生成函数、分治
传送门 首先,每一次有一个猎人死亡之后\(\sum w\)会变化,计算起来很麻烦,所以考虑在某一个猎人死亡之后给其打上标记,仍然计算他的\(w\),只是如果打中了一个打上了标记的人就重新选择.这样对应 ...
- [LOJ2541][PKUWC2018]猎人杀(容斥+分治+FFT)
https://blog.csdn.net/Maxwei_wzj/article/details/80714129 n个二项式相乘可以用分治+FFT的方法,使用空间回收可以只开log个数组. #inc ...
- [LOJ2541] [PKUWC2018] 猎人杀
题目链接 LOJ:https://loj.ac/problem/2541 Solution 很巧妙的思路. 注意到运行的过程中概率的分母在不停的变化,这样会让我们很不好算,我们考虑这样转化:假设所有人 ...
- [PKUWC2018]猎人杀
题解 感觉是一道神题,想不出来 问最后\(1\)号猎人存活的概率 发现根本没法记录状态 每次转移的分母也都不一样 可以考虑这样一件事情: 如果一个人被打中了 那么不急于从所有人中将ta删除,而是给ta ...
- 题解-PKUWC2018 猎人杀
Problem loj2541 题意概要:给定 \(n\) 个人的倒霉度 \(\{w_i\}\),每回合会有一个人死亡,每个人这回合死亡的概率为 自己的倒霉度/目前所有存活玩家的倒霉度之和,求第 \( ...
- 洛谷 P5644 - [PKUWC2018]猎人杀(分治+NTT)
题面传送门 很久之前(2020 年)就听说过这题了,这么经典的题怎么能只听说而亲自做一遍呢 首先注意到每次开枪打死一个猎人之后,打死其他猎人概率的分母就会发生变化,这将使我们维护起来非常棘手,因此我们 ...
- 【洛谷5644】[PKUWC2018] 猎人杀(容斥+生成函数+分治NTT)
点此看题面 大致题意: 有\(n\)个人相互开枪,每个人有一个仇恨度\(a_i\),每个人死后会开枪再打死另一个还活着的人,且第一枪由你打响.设当前剩余人仇恨度总和为\(k\),则每个人被打中的概率为 ...
- 【LOJ2541】【PKUWC2018】猎人杀(容斥,FFT)
[LOJ2541][PKUWC2018]猎人杀(容斥,FFT) 题面 LOJ 题解 这题好神仙啊. 直接考虑概率很麻烦,因为分母总是在变化. 但是,如果一个人死亡之后,我们不让他离场,假装给他打一个标 ...
- 「PKUWC2018」猎人杀
「PKUWC2018」猎人杀 解题思路 首先有一个很妙的结论是问题可以转化为已经死掉的猎人继续算在概率里面,每一轮一直开枪直到射死一个之前没死的猎人为止. 证明,设所有猎人的概率之和为 \(W\) , ...
随机推荐
- Python 命令行解析工具 Argparse介绍
最近在研究pathon的命令行解析工具,argparse,它是Python标准库中推荐使用的编写命令行程序的工具. 以前老是做UI程序,今天试了下命令行程序,感觉相当好,不用再花大把时间去研究界面问题 ...
- linux命令系列 grep
grep, egrep, fgrep - print lines matching a pattern SYNOPSIS grep [OPTIONS] PATTERN [FILE...] grep [ ...
- LeetCode 404. Sum of Left Leaves (C++)
题目: Find the sum of all left leaves in a given binary tree. Example: 3 / \ 9 20 / \ 15 7 There are t ...
- Final阶段版本控制报告
版本控制代码及文档要求 在coding.net版本控制; 公开项目,教师.专家.其他同学可以不注册源代码.在此公布git地址. 报告beta阶段2周中,项目的版本控制情况,不包括未在coding.ne ...
- Daily Scrum5 11.7
今日任务: 姓名 任务 时长 徐钧鸿 学习了java连接sqlserver的方法并且实现了连接池 2h 张艺 继续完成和用户管理有关的类的移植(Register.Success.Validate等) ...
- Scrum Meeting 10.31
成员 今日任务 明日任务 今日工作时长 徐越 整理开发文档,学习ip相关知识,学习servlet相关知识 代码迁移,学习数据库相关知识 5h 赵庶宏 学习学长的servlet代码 进行数据库的连接 4 ...
- Sprint计划表
Sprint会议计划 一.Sprint 需求 准备环节:小组成员利用周六周日在网上查阅Android开发的教程,练习开发一些简单的小程序,具备一定的开发能力,在电脑上搭建Android开发环境,做好 ...
- android 的helloworld没跑起来 原因
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com. ...
- 20181126-java-面试知识-收集
链接:最近面试java后端开发的感受:如果就以平时项目经验来面试,通过估计很难——再论面试前的准备 两本书的链接:Java Web轻量级开发面试教程和Java核心技术及面试指南.
- 软工网络15团队作业8——Beta阶段敏捷冲刺(Day5)
提供当天站立式会议照片一张 每个人的工作 1.讨论项目每个成员的昨天进展 赵铭: 进一步数据整理,写入数据库. 吴慧婷:主页面.查单词页面的改进.背单词界面改进. 陈敏: 单词学习功能及该界面按钮功能 ...