题解

一道神仙的题><

我们毙掉一个人后总的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;
}

最新文章

  1. JavaScript中的slice,splice,substr,substring,split的区别
  2. FFmpeg-for IOS 一[安装]
  3. JS截取,删除,替换字符串常用方法详细
  4. jquery note--czx
  5. openwrt简单ipk生成及Makefile解释
  6. Highcharts选项配置详细说明文档(zz)
  7. windows下游戏服务器端框架Firefly安装说明及demo运行
  8. BZOJ 4407 于神之怒加强版
  9. Java getResourceAsStream返回为空的问题
  10. Web设计中打开新页面或页面跳转的方法 js跳转页面
  11. yii2图片验证码
  12. [O]SQL SERVER下有序GUID和无序GUID作为主键&amp;聚集索引的性能表现
  13. framework7 入门(数据获取和传递)
  14. Java中string.equalsIgnoreCase(&quot;0&quot;)与&quot;0&quot;.equalsIgnoreCase(string)的区别:
  15. 第三十七节、人脸检测MTCNN和人脸识别Facenet(附源码)
  16. 【C语言程序】基因编码
  17. ubuntu通过apt-get安装JDK8
  18. 《Linux内核设计与实现》读书笔记 4 进程调度
  19. C++面试题:list和vector有什么区别
  20. 006使用Grafana展示时间序列数据

热门文章

  1. java基础-回调函数(callback)
  2. 科学计算三维可视化---TVTK入门(创建和显示三维对象)
  3. bzoj千题计划142:bzoj3144: [Hnoi2013]切糕
  4. 51nod 1181 质数中的质数
  5. Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第七部分(Page 12)
  6. Ubuntu下hadoop环境的搭建(伪分布模式)
  7. 利用phpMyAdmin提权
  8. CSS line-height与行内框
  9. spring-boot-单元测试参数数
  10. Intent 对象在 Android 开发中的应用