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}\) ,问期望步 ...
随机推荐
- 14 Scroll 滚动搜索
Scroll的用法: 第一次搜的时候,要指定 快照保留时间1min,分页的大小:2条/页: 对于第一次搜索,ES会返回一个这个scroll的id: 下次再搜的时候,就带着这个scrollid去搜就 ...
- idea: unable to import maven project
新搭建的maven环境,使用idea创建maven项目时,一直提示 unable to import maven project,百度良久未解决 有说关闭防火前的,亲测无效,后看到说是maven-3. ...
- 【转载】 C#使用Math.Abs返回数值的绝对值
在C#的数值运算中,有时候我们需要计算值类型对象的绝对值,此时需要用到C#的数值计算类Math类中的Abs绝对值函数,Math.Abs绝对值函数一共有7个重载类型,支持decimal.double.f ...
- vue实现滑块滑动校验
为了防止机器操作自动提交,我们需要添加滑动校验. 实现代码如下: 1.子组件slider.vue <template> <div class="drag" r ...
- “http”和“https”的区别是什么?优缺点是什么?
1. http 的URL 以http:// 开头,https以https:// 开头. 2. http 标准端口是80 ,https是443. 3.https 协议需要到ca申请证书,http不需要. ...
- mybatis异常:nested exception is org.apache.ibatis.builder.BuilderException: Error resolving JdbcType
异常详细 org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.Builde ...
- Nginx 操作响应头信息的实现
前置条件:需要编译 ngx_http_headers_module 模块,才支持 header 头信息操作 add_header 意思为将自定义的头信息的添加到响应头,指令为 add_header n ...
- Laravel5.6---搜索查询 自带paginate()分页 get传参
laravel的paginate()分页,如果用post传参,点击第二页时会默认使用get,就会返回原始数据了 需要把查询数据get方式也放到paginate()分页参数中 一.路由 Route::g ...
- HTTP协议复习三--TCP/IP的网络分层模型和OSI 网络分层模型
TCP/IP网络分层模型 第一层叫“链接层”(link layer),负责在以太网.WiFi这样的底层网络上发送原始数据包,工 作在网卡这个层次,使用MAC地址来标记网络上的设备,所以有时候也叫MAC ...
- 「8-27
没有别的目的, 是最近发现一个小软件, 用起来感觉很不错, 所以想分享给大家. 首先这是一个 macOS 软件, 它的功能也很简单, 就是在菜单栏显示日期时间, 点按它可以显示日历, 没错, 简单到是 ...