UOJ#469. 【ZJOI2019】开关 生成函数
原文链接www.cnblogs.com/zhouzhendong/p/UOJ469.html
前言
clytql当场秒掉此题可惜不知道为什么fst了。
题解
考虑构建指数生成函数。
对于第 \(i\) 项,设其概率为 \(p_i\) (即题目中的 \(p_i / \sum_i p_i\)) 。构建指数生成函数:
\]
\(F(x) = \prod_i f_i(x) ,f(x) = \sum_{i} i! [x^i]F(x)\) 的 \(k\) 次项系数就是随机按 \(k\) 次开关到达指定状态的概率。
我们要求的是第一次到达指定状态的概率,所以我们需要将多项式 \(f(x)\) 除去"\(s_i\) 全为 0 时的多项式 \(g(x)\)"。
我们要算的是期望,所以我们要求的是
\]
的各个系数之和。注意由于我们在求 \(f(x)\)、\(g(x)\) 时,就已经乘了一个阶乘将指数生成函数转化成对应的普通生成函数了。因为我们要除去的方案是从终止状态出发再回到终止状态的方案数(OGF),而不是在到达终止状态之前绕一圈的方案数(如果除以EGF)。
由于
\]
于是,我们来对每一个项考虑一下:
\]
\]
\]
\]
接下来我们把 \(x = 1\) 代入求解。
考虑到当 \(k = 1\) 时我们会得到 NAN,这导致了求解失败。
但是我们显然可以肯定答案不是 NAN。那么发生了什么?
之前提到,答案是
\]
我们只需要将分子分母上下同乘 \((1-kx) ^ 2\) 。
注意到 \(g^2(x)\) 里面有 \(\cfrac {1}{(1-kx) ^ 2}\) ,但是 $f'(x) g(x) $ 和 \(f(x)g'(x)\) 里面都有 \(\cfrac {1}{(1-kx) ^ 3}\) ,看起来似乎又是 NAN。注意到 $f'(x) g(x) $ 和 \(f(x)g'(x)\) 里面的 \(\cfrac {1}{(1-kx) ^ 3}\) 项在减法时抵消了,所以没有影响。
总时间复杂度 \(O(n \sum{p_ i} )\) 。
代码
#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof x)
#define For(i,a,b) for (int i=(a);i<=(b);i++)
#define Fod(i,b,a) for (int i=(b);i>=(a);i--)
#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define outval(x) cerr<<#x" = "<<x<<endl
#define outtag(x) cerr<<"---------------"#x"---------------"<<endl
#define outarr(a,L,R) cerr<<#a"["<<L<<".."<<R<<"] = ";\
For(_x,L,R)cerr<<a[_x]<<" ";cerr<<endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> vi;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int N=105,S=1e5+10,mod=998244353;
int Pow(int x,int y){
int ans=1;
for (;y;y>>=1,x=(LL)x*x%mod)
if (y&1)
ans=(LL)ans*x%mod;
return ans;
}
void Add(int &x,int y){
if ((x+=y)>=mod)
x-=mod;
}
void Del(int &x,int y){
if ((x-=y)<0)
x+=mod;
}
int Add(int x){
return x>=mod?x-mod:x;
}
int Del(int x){
return x<0?x+mod:x;
}
int inv2=(mod+1)>>1;
int n;
int s[N],p[N],sum=0,invs;
int f[S],g[S],val[S],inv[N],O=5e4+5;
int ans=0;
void Get(int *a){
static int b[S];
For(i,-sum,sum){
a[i+O]=0;
val[i+O]=(LL)Del(i)*invs%mod;
inv[i+O]=Pow(Del(1-val[i+O]),mod-2);
}
a[0+O]=1;
For(i,1,n){
For(j,-sum,sum)
b[j+O]=0;
For(j,-sum,sum){
if (!a[j+O])
continue;
Add(b[j+p[i]+O],a[j+O]);
if (s[i])
Del(b[j-p[i]+O],a[j+O]);
else
Add(b[j-p[i]+O],a[j+O]);
}
For(j,-sum,sum)
a[j+O]=b[j+O];
}
}
int calc1(int *a,int *b){
// a' * b * (1 - x) ^ 2
int ans=0;
For(i,-sum,sum-1)
Add(ans,(LL)b[i+O]*inv[i+O]%mod);
ans=(LL)ans*a[sum+O]%mod;
return ans;
}
int calc2(int *a){
return (LL)a[sum+O]*a[sum+O]%mod;
}
int main(){
n=read();
For(i,1,n)
s[i]=read();
For(i,1,n)
p[i]=read(),sum+=p[i];
invs=Pow(sum,mod-2);
Get(f),clr(s),Get(g);
Add(ans,calc1(f,g));
Del(ans,calc1(g,f));
ans=(LL)ans*Pow(calc2(g),mod-2)%mod;
cout<<ans<<endl;
return 0;
}
UOJ#469. 【ZJOI2019】开关 生成函数的更多相关文章
- [ZJOI2019] 开关 (一种扩展性较高的做法)
[ZJOI2019] 开关 (一种扩展性较高的做法) 题意: 有n个开关,一开始状态都为关闭.每次随机选出一个开关将其状态改变,选出第i个开关的概率为${ p_i \over \sum_{i=1}^n ...
- [ZJOI2019]开关(生成函数+背包DP)
注:以下p[i]均表示概率 设F(x)为按i次开关后到达终止状态方案数的EGF,显然F(x)=π(ep[i]x/p+(-1)s[i]e-p[i]x/p)/2,然而方案包含一些多次到达合法方案的状态,需 ...
- [ZJOI2019]开关
以下的方案数默认是带权方案数.设\(P=\sum_{i=1}^np_i\). 设\(F(x)\)为按\(i\)次开关后到达终止态的方案数的EGF,\(f\)为\(F\)的OGF,显然\(F(x)=\p ...
- 【UOJ#450】【集训队作业2018】复读机(生成函数,单位根反演)
[UOJ#450][集训队作业2018]复读机(生成函数,单位根反演) 题面 UOJ 题解 似乎是\(\mbox{Anson}\)爷的题. \(d=1\)的时候,随便怎么都行,答案就是\(k^n\). ...
- Loj #3045. 「ZJOI2019」开关
Loj #3045. 「ZJOI2019」开关 题目描述 九条可怜是一个贪玩的女孩子. 这天,她和她的好朋友法海哥哥去玩密室逃脱.在他们面前的是 \(n\) 个开关,开始每个开关都是关闭的状态.要通过 ...
- LOJ 3045: 洛谷 P5326: 「ZJOI2019」开关
题目传送门:LOJ #3045. 题意简述 略. 题解 从高斯消元出发好像需要一些集合幂级数的知识,就不从这个角度思考了. 令 \(\displaystyle \dot p = \sum_{i = 1 ...
- UOJ#450. 【集训队作业2018】复读机 排列组合 生成函数 单位根反演
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ450.html 题解 首先有一个东西叫做“单位根反演”,它在 FFT 的时候用到过: $$\frac 1 ...
- uoj#335. 【清华集训2017】生成树计数(prufer序列+生成函数+多项式)
传送门 好神仙的题目--又一次有了做一题学一堆的美好体验 据说本题有第二类斯特林数+分治\(FFT\)的做法,然而咱实在看不懂写的是啥,题解贴这里,有兴趣的可以自己去瞅瞅,看懂了记得回来跟咱讲讲 前置 ...
- 【loj3045】【ZJOI2019】开关
题目 \(n\)个开关,一开始处于关闭状态,你需要将他们按成\(s\)状态,按成了之后就停止操作; 每次按下开关的i概率为\(\frac{p_i}{\sum_{i=1}^{n}p_i}\) ,问期望步 ...
随机推荐
- flutter 动画 practice
import 'package:flutter/material.dart'; import 'dart:io'; import 'dart:async'; main() => runApp(M ...
- dubbo源码阅读之服务导出
dubbo服务导出 常见的使用dubbo的方式就是通过spring配置文件进行配置.例如下面这样 <?xml version="1.0" encoding="UTF ...
- iOS - 适配iOS 11
http://www.10tiao.com/html/330/201707/2653579210/1.html 存档 导语:iOS 11 为整个生态系统的 UI 元素带来了一种更加大胆.动态的新风格. ...
- 智表(ZCELL)插件产品选型说明书,市场主流插件对比,帮您选型
智表(ZCELL)插件产品选型说明书,市场主流插件对比,帮您选型. 说明书下载:地址 一. 我们为什么需要智表插件产品 客户早已养成EXCEL中的操作习惯,BS架构下,普通的网页交互,与客户习惯 ...
- layui.js源码分析
/*! @Title: Layui @Description:经典模块化前端框架 @Site: www.layui.com @Author: 贤心 @License:MIT */ ;!functi ...
- jar包下载网站
https://mvnrepository.com/ https://www.kumapai.com/open/query/?querytype=title&querykey=cglib ht ...
- c# CryptoStream 类
- SCADA系统构架的安全分析总结
概念: SCADA 数据采集与监控 Supervisory Control And Data Acquisition .包括了计算机设备 工业控制组件 网络 组成部件 ,SCADA 系统被用 ...
- [https][tls] 如何使用wireshark查看tls/https加密消息--使用keylog
姊妹篇: [ipsec][strongswan] 使用wireshark查看strongswan ipsec esp ikev1 ikev2的加密内容 [https][tls] 如何使用wiresha ...
- Vim编译器的相关知识
Vim编译器相关知识 1.关于Vim编译器 在热门Linux操作系统中都会默认安装一款超好用的文本编辑器——名字叫“vim”,vim是vi编辑器的升级版. vim 具有程序编辑的能力,可以主动的以字体 ...