LOJ2541. 「PKUWC2018」猎人杀 [概率,分治NTT]
思路
好一个神仙题qwq
首先,发现由于一个人死之后分母会变,非常麻烦,考虑用某种方法定住分母。
我们稍微改一改游戏规则:一个人被打死时只打个标记,并不移走,也就是说可以被打多次但只算一次。容易发现这并不影响最终结果。
然而光想到这个好像没什么用?
再考虑容斥:枚举哪些人在1之后被打死,其他随意。设在1后面的人的权值为\(S\),总权值为\(sum\),那么概率就是
&\sum_{i=0}^{\infty} (1-\frac{w_1+S}{sum})^i\frac{w_1}{sum}\\
=&\frac{w_1}{sum}\times \frac{sum}{S+w_1}\\
=&\frac{w_1}{w_1+S}
\end{align*}
\]
(上式表示枚举打了几枪之后打到1)
而容斥系数是\((-1)^{人数}\)。
由于\(\sum w\)很小,可以考虑背包算出\(S\)的贡献,但跑不过去。
用分治NTT优化背包即可,每个人的生成函数是\(1-x^{w_i}\),对应每多一个人容斥系数就乘\(-1\)。
代码
#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define templ template<typename T>
#define sz 404004
#define mod 998244353ll
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
templ inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
char __sr[1<<21],__z[20];int __C=-1,__zz=0;
inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
inline void print(register int x)
{
if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
while(__z[++__zz]=x%10+48,x/=10);
while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
}
void file()
{
#ifdef NTFOrz
freopen("a.in","r",stdin);
#endif
}
inline void chktime()
{
#ifndef ONLINE_JUDGE
cout<<(clock()-t)/1000.0<<'\n';
#endif
}
#ifdef mod
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
ll inv(ll x){return ksm(x,mod-2);}
#else
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
#endif
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;
int r[sz],limit;
void NTT_init(int n)
{
int l=-1;
for (limit=1;limit<=n;limit<<=1) ++l;
rep(i,0,limit-1) r[i]=(r[i>>1]>>1)|((i&1)<<l);
}
void NTT(ll *a,int type)
{
rep(i,0,limit-1) if (i<r[i]) swap(a[i],a[r[i]]);
for (int mid=1;mid<limit;mid<<=1)
{
ll Wn=ksm(3,(mod-1)/mid>>1);if (type==-1) Wn=inv(Wn);
for (int len=mid<<1,j=0;j<limit;j+=len)
{
ll w=1;
for (int k=0;k<mid;k++,w=w*Wn%mod)
{
ll x=a[j+k],y=w*a[j+k+mid]%mod;
a[j+k]=(x+y)%mod;a[j+k+mid]=(x-y+mod)%mod;
}
}
}
if (type==1) return;
ll I=inv(limit);
rep(i,0,limit-1) a[i]=a[i]*I%mod;
}
int n;
int w[sz];
ll tmp[60][sz];
int st[60],top;
int len[60];
int work(int l,int r)
{
if (l==r){int k=st[top--];tmp[k][0]=1;tmp[k][w[l]]=mod-1;len[k]=w[l];return k;}
int mid=(l+r)>>1,L=work(l,mid),R=work(mid+1,r);
int k=st[top--];
NTT_init(len[L]+len[R]+2);
NTT(tmp[L],1);NTT(tmp[R],1);
rep(i,0,limit-1) tmp[L][i]=tmp[L][i]*tmp[R][i]%mod;
NTT(tmp[L],-1);
rep(i,0,len[L]+len[R]) tmp[k][i]=tmp[L][i];
len[k]=len[L]+len[R];
rep(i,0,limit-1) tmp[L][i]=tmp[R][i]=0;
st[++top]=L;st[++top]=R;
return k;
}
int main()
{
file();
read(n);
int sum=0;
rep(i,1,n) read(w[i]),sum+=w[i];
rep(i,1,50) st[++top]=i;
int k=work(2,n);
ll ans=0;
rep(i,0,sum-w[1]) (ans+=tmp[k][i]*inv(w[1]+i)%mod)%=mod;
ans=ans*w[1]%mod;
cout<<ans;
return 0;
}
LOJ2541. 「PKUWC2018」猎人杀 [概率,分治NTT]的更多相关文章
- loj2541 「PKUWC2018」猎人杀 【容斥 + 分治NTT】
题目链接 loj2541 题解 思路很妙啊, 人傻想不到啊 觉得十分难求,考虑容斥 由于\(1\)号可能不是最后一个被杀的,我们容斥一下\(1\)号之后至少有几个没被杀 我们令\(A = \sum\l ...
- [LOJ2541]「PKUWC2018」猎人杀
loj description 有\(n\)个猎人,每个猎人有一个仇恨度\(w_i\),每个猎人死后会开一枪打死一个还活着的猎人,打中每个猎人的概率与他的仇恨度成正比. 现在你开了第一枪,打死每个猎人 ...
- 「PKUWC2018」猎人杀
「PKUWC2018」猎人杀 解题思路 首先有一个很妙的结论是问题可以转化为已经死掉的猎人继续算在概率里面,每一轮一直开枪直到射死一个之前没死的猎人为止. 证明,设所有猎人的概率之和为 \(W\) , ...
- 【LOJ】#2541. 「PKUWC2018」猎人杀
题解 一道神仙的题>< 我们毙掉一个人后总的w的和会减少,怎么看怎么像指数算法 然而,我们可以容斥-- 设\(\sum_{i = 1}^{n} w_{i} = Sum\) 我们把问题转化一 ...
- loj#2541. 「PKUWC2018」猎人杀
传送门 思路太清奇了-- 考虑容斥,即枚举至少有哪几个是在\(1\)号之后被杀的.设\(A=\sum_{i=1}^nw_i\),\(S\)为那几个在\(1\)号之后被杀的人的\(w\)之和.关于杀了人 ...
- LOJ 2541 「PKUWC2018」猎人杀——思路+概率+容斥+分治
题目:https://loj.ac/problem/2541 看了题解才会……有三点很巧妙. 1.分母如果变动,就很不好.所以考虑把操作改成 “已经选过的人仍然按 \( w_i \) 的概率被选,但是 ...
- LOJ #2541「PKUWC2018」猎人杀
这样$ PKUWC$就只差一道斗地主了 假装补题补完了吧..... 这题还是挺巧妙的啊...... LOJ # 2541 题意 每个人有一个嘲讽值$a_i$,每次杀死一个人,杀死某人的概率为$ \fr ...
- 洛谷 P5644 - [PKUWC2018]猎人杀(分治+NTT)
题面传送门 很久之前(2020 年)就听说过这题了,这么经典的题怎么能只听说而亲自做一遍呢 首先注意到每次开枪打死一个猎人之后,打死其他猎人概率的分母就会发生变化,这将使我们维护起来非常棘手,因此我们 ...
- loj2541【PKUWC2018】猎人杀
题解 题目中的选择条件等价于正常选择所有猎人,而如果选到已经出局的猎人就继续选: 这两种选法是一样的因为(设$W=\sum_{i=1}^{n}w_{i}$ , $X$为已经出局的猎人的$w$之和): ...
随机推荐
- 音视频入门-07-认识YUV
* 音视频入门文章目录 * YUV & YCbCr 简介 YUV,是一种颜色编码方法.常使用在各个视频处理组件中. YUV 在对照片或视频编码时,考虑到人类的感知能力,允许降低色度的带宽. Y ...
- VS.NET(C#)--1.4项目与解决方案
项目与解决方案 项目 除创建网站,VS2005可创建项目.然后把项目放入解决方案中.VS2005可编译很多类型项目,分别是: 1.Windows应用程序 --在用戶计算机上运行的客户端应用程序,可显示 ...
- sql server中:isnull(列名,0) 和isnull(列名,0)<>0 的区别
1.isnull(参数1,参数2),判断参数1是否为NULL,如果是,返回参数2,否则返回参数1. 2.isnull(列名,0),isnull()函数是用来判断列名是否为null,如果为NUll,则返 ...
- Nginx快速自查手册
本项目是一个 Nginx 极简教程,目的在于帮助新手快速入门 Nginx. demos 目录中的示例模拟了工作中的一些常用实战场景,并且都可以通过脚本一键式启动,让您可以快速看到演示效果. 概述 什么 ...
- 在Windows上安装Redis
微软官网源码 https://github.com/MicrosoftArchive/redis 这里介绍安装Signed binaries版本 使用Chocolatey(Windows包管理工具)安 ...
- jQuery笔试题汇总整理
1 你在公司是怎么用jquery的? 答:在项目中是怎么用的是看看你有没有项目经验(根据自己的实际情况来回答) 你用过的选择器啊,动画啊,表单啊,ajax事件等 配置Jquery环境 下载jquery ...
- K2 BPM_加班党们,说好不哭还是说好不秃?_流程管理
早上经过财务小陈的办公桌 看到她正边看手机边默默流泪 诶?这不是这两天刷屏的 周杰伦的<说好不哭>吗 小陈你怎么哭啦,这歌让你想到前男友了吗? ...... (摇头) 小陈擦擦眼泪 唱起了 ...
- Eclipse workspace被锁定
重新打开Eclipse时,提示如下: Workspace Unavailable: Workspace in use or cannot be created, choose a different ...
- Android笔记(三十一)Android中线程之间的通信(三)子线程给主线程发送消息
先看简单示例:点击按钮,2s之后,TextView改变内容. package cn.lixyz.handlertest; import android.app.Activity; import and ...
- Dumpsys Alarm查看应用程序唤醒命令
Dumpsys alarm查看应用程序唤醒命令: 在安卓adb root进如命令行后(没有root或者root群组的权限执行不了该命令), 1. <span style="font-s ...