[ZJOI2019]开关
以下的方案数默认是带权方案数。设\(P=\sum_{i=1}^np_i\)。
设\(F(x)\)为按\(i\)次开关后到达终止态的方案数的EGF,\(f\)为\(F\)的OGF,显然\(F(x)=\prod_{i=1}^n\frac{e^{\frac{p_ix}{P}}+(-1)^{s_i}e^{\frac{-p_ix}{P}}}{2}\)。初步的想法就是用\(f'(1)\)计算答案,但是这样是错误的,因为可能存在一些操作序列多次到达过终止态,这样就被重复计算了。设\(h(x)\)为按\(i\)次开关后第一次到达终止态的方案数的OGF,那么答案应该是\(h'(1)\)。
考虑怎样计算\(h\)。可以发现,\(f_i\)等于枚举一个前缀,使得进行完这个前缀的操作后第一次到达终止态,再进行剩下的操作回到这个原状态的方案数之和。设\(G\)为\(i\)次操作后回到原状态的方案数的EGF,\(g\)为\(G\)的OGF,显然\(G(x)=\prod_{i=1}^n\frac{e^{\frac{p_ix}{P}}+e^{\frac{-p_ix}{P}}}{2}\)。如果我们能求出\(f\)和\(g\),那么\(gh=f,h=\frac{f}{g}\)。
考虑将\(F\)表示为\(\sum_{i=-P}^Pa_ie^{\frac{ix}{p}}\)的形式,把\(e\)拆开,每一项乘上对应的阶乘,可以得到\(f=\frac{a_i}{1-\frac{ix}{p}}\)。\(G\)同理。考虑怎样求\(h'(1)\),用公式\((\frac{f}{g})'=\frac{f'g+g'f}{g^2}\)计算答案。但是把\(x=1\)代入\(f,g\)不收敛,所以把\(f,g\)同时乘上\(\prod_{i=-P}^P(1-\frac{ix}{p})\)。
剩下就是推式子的事了。
#include <bits/stdc++.h>
using namespace std;
const int N = 5e4 + 10;
const int mod = 998244353;
const int inv2 = (mod + 1) >> 1;
#define ms(a) memset(a,0,sizeof(a))
#define mc(a,b) memcpy(a,b,sizeof(a))
int n, s[N], p = 0, f[N << 1], g[N << 1], h[N << 1];
void inc(int &a, int b) {
a += b;
if(a >= mod) {
a -= mod;
}
}
int qpow(int a, int b) {
int ret = 1;
while(b) {
if(b & 1) {
ret = 1ll * ret * a % mod;
}
a = 1ll * a * a % mod, b >>= 1;
}
return ret;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("a.in", "r", stdin);
freopen("a.out", "w", stdout);
#endif
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", s + i);
}
f[N] = g[N] = 1;
for(int i = 1, x; i <= n; i++) {
scanf("%d", &x);
for(int j = -p; j <= p; j++) {
inc(h[j + x + N], 1ll * f[j + N]*inv2 % mod), inc(h[j - x + N], 1ll * f[j + N]*inv2 % mod * (s[i] ? mod - 1 : 1) % mod);
}
mc(f, h);
ms(h);
for(int j = -p; j <= p; j++) {
inc(h[j + x + N], 1ll * g[j + N]*inv2 % mod), inc(h[j - x + N], 1ll * g[j + N]*inv2 % mod);
}
mc(g, h);
ms(h);
p += x;
}
int ans = 0;
for(int i = -p; i < p; i++) {
inc(ans, 1ll * (g[i + N] - f[i + N] + mod)*qpow(p - i, mod - 2) % mod);
}
cout << 1ll * ans*p % mod*qpow(2, n) % mod;
return 0;
}
[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,然而方案包含一些多次到达合法方案的状态,需 ...
- Loj #3045. 「ZJOI2019」开关
Loj #3045. 「ZJOI2019」开关 题目描述 九条可怜是一个贪玩的女孩子. 这天,她和她的好朋友法海哥哥去玩密室逃脱.在他们面前的是 \(n\) 个开关,开始每个开关都是关闭的状态.要通过 ...
- 【loj3045】【ZJOI2019】开关
题目 \(n\)个开关,一开始处于关闭状态,你需要将他们按成\(s\)状态,按成了之后就停止操作; 每次按下开关的i概率为\(\frac{p_i}{\sum_{i=1}^{n}p_i}\) ,问期望步 ...
- 「ZJOI2019」开关
传送门 Description 有一些一开始全都是关的开关,每次随机选择一个(每个开关概率不同)开关并改变它的状态,问达到目标状态的期望步数 Solution \(P=\sum_{i=1}^{n}p ...
- UOJ#469. 【ZJOI2019】开关 生成函数
原文链接www.cnblogs.com/zhouzhendong/p/UOJ469.html 前言 clytql当场秒掉此题可惜不知道为什么fst了. 题解 考虑构建指数生成函数. 对于第 \(i\) ...
- LOJ 3045: 洛谷 P5326: 「ZJOI2019」开关
题目传送门:LOJ #3045. 题意简述 略. 题解 从高斯消元出发好像需要一些集合幂级数的知识,就不从这个角度思考了. 令 \(\displaystyle \dot p = \sum_{i = 1 ...
- ZJOI2019一轮游记
Preface 期待已久的省选终于开始了233,关于之前的一些内容,在ZJOI2019一轮停课刷题记录都可以找到,这里不再赘述 ZJOI2019,Bless All Day -1 今天难得有休息,昨晚 ...
- 手游聚合SDK开发之远程开关---渠道登入白名单
白名单有啥好说的呢?无非就是筛选登入,大家第一眼看到就是这个印象,白名单也是有文章的,弄的时机不同会给你带来很不错的收益,注意是收益.还是举例来说,游戏上线前渠道都会做一个预下载,一般提前1-2天,这 ...
随机推荐
- Gitlab仓库搭建和免密使用gitlab
Gitlab简介 GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务. 可通过Web界面进行访问公开的或者私人项目.它拥有与Github类似的 ...
- Linux下jdk1.6安装指引
Linux安装JDK步骤1. 先从网上下载jdk(jdk-6u4-linux-x64-rpm.bin) ,推荐SUN的官方网站www.sun.com,下载后放在/home目录中,当然其它地方也行. 进 ...
- Python web自动化测试框架搭建(功能&接口)——unittest介绍
Python UnitTest测试框架介绍 1) TestCase:所有测试用例类继承的基本类, TestCase的实例就是测试用例 2) TestSuite:测试套件 ...
- tp框架视图层view——模板继承
在做网站的时候,每个网站都有头部和尾部,也就是菜单栏和页脚,网站的各个子网页的头部和尾部基本就是一样的,所以tp框架提供了一种模板继承的方法: 1.首先在View的Main文件夹下建立一个base.h ...
- Go-Mutex互斥量
先来看一段go1.12.5中Mutex的源码: // Copyright 2009 The Go Authors. All rights reserved. // Use of this source ...
- TCGA癌症缩写、癌症中英文对照
Cohort 英文名称 中文名称 ACC Adrenocortical carcinoma 肾上腺皮质癌 BLCA Bladder Urothelial Carcinoma 膀胱尿路上皮癌 BRCA ...
- 《JAVA设计模式》之外观模式(Facade)
在阎宏博士的<JAVA与模式>一书中开头是这样描述门面(Facade)模式的: 门面模式是对象的结构模式,外部与一个子系统的通信必须通过一个统一的门面对象进行.门面模式提供一个高层次的接口 ...
- tp增删改查
增: 向数据库增加新的数据,这里增是纯粹的增添数据,如果新增的数据包含主键,并且该主键已经在数据库存在,则无法新增数据的. //M("User") 用于高效实例化一个数据模型(M ...
- jQuery easyUI 使用 datagrid 表格
获取后台数据依旧是使用一般处理程序(ashx) ,分页上添加一个函数(pagerFilter(data)) 前端代码: <%@ Page Language="C#" Auto ...
- Java中POJO及其细分XO、DAO的概念
各层命名规约: A) Service/DAO 层方法命名规约 1) 获取单个对象的方法用 get 做前缀. 2) 获取多个对象的方法用 list 做前缀. 3) 获取统计值的方法用 count 做前缀 ...