Loj #3045. 「ZJOI2019」开关

题目描述

九条可怜是一个贪玩的女孩子。

这天,她和她的好朋友法海哥哥去玩密室逃脱。在他们面前的是 \(n\) 个开关,开始每个开关都是关闭的状态。要通过这关,必须要让开关达到指定的状态。目标状态由一个长度为 \(n\) 的 \(01\) 数组 \(s\) 给出,\(s_i = 0\) 表示第 \(i\) 个开关在最后需要是关着的,\(s_i = 1\) 表示第 \(i\) 个开关在最后需要被打开。

然而作为闯关者,可怜和法海并不知道 \(s\)。因此他们决定采用一个比较稳妥的方法:瞎按。他们根据开关的外形、位置,通过一些玄学的方法给每一个开关赋予了一个值 \(p_i(p_i > 0)\)。每一次,他们会以正比于 \(p_i\) 的概率(第 \(i\) 个开关被选中的概率是 \(\frac{p_i}{\sum_{j=1}^n p_j}\))选择并按下一个开关。开关被按下后,状态会被反转,即开变关,关变开。注意,每一轮的选择都是完全独立的

在按开关的过程中,一旦当前开关的状态达到了 \(s\),那么可怜和法海面前的门就会打开,他们会马上停止按开关的过程并前往下一关。作为一名欧皇,可怜在按了\(\sum_{i=1}^n s_i\) 次后,就打开了大门。为了感受一下自己的运气是多么的好,可怜想要让你帮她计算一下,用这种随机按的方式,期望需要按多少次开关才能通过这一关。

输入格式

第一行输入一个整数 \(n\),表示开关的数量。

第二行输入 \(n\) 个整数 \(s_i(s_i \in \{0, 1\})\),表示开关的目标状态。第三行同样输入 \(n\) 个整数 \(p_i\),表示每个开关的权值。

输出格式

输出一行一个整数,表示答案对 \(998244353\) 取模后的值。即如果答案的最简分数表示为 \(\frac{x}{y}\ (x \ge 0, y \ge 1, \gcd(x, y) = 1)\),你需要输出 \(x \times y^{−1} \bmod 998244353\)。

数据范围与提示

对于 \(100\%\) 的测试数据,保证 \(n\ge 1,\sum_{i=1}^n p_i\le 5\times 10^4,p_i\ge 1\)。

\(\\\)

完全不会啊,还是\(\text{Orz}\)别人的题解好了。https://www.cnblogs.com/zhoushuyu/p/10687696.html

首先设\(P=\sum_{i=1}^np_i\)

为了方便,下面的\(p_i=\frac{p_i}{P}\)。

先求出走了\(n\)步到达结束状态的概率的\(EGF\):

考虑当\(s_i\)为\(1\)的时候,结束状态时应该按了\(i\)奇数次,否则按了偶数次。

我们也知道:

\[\frac{e^x-e^{-x}}{2}=\sum_{i\ is\ odd}\frac{x^i}{i!}\\
\frac{e^x+e^{-x}}{2}=\sum_{i\ is\ even}\frac{x^i}{i!}\\
\]

所以概率的\(EGF\)为:

\[F(x)=\prod_{i=1}^n\frac{e^{p_ix}+(-1)^{s_i}e^{-p_ix}}{2}
\]

但是有可能在走完\(n\)步之前就经过了终止状态。全过程可以认为是先走到了终止状态,再绕了若干圈回到终止状态。

考虑走了\(n\)步回到出发点的概率的\(EGF\):

\[G(x)=\prod_{i=1}^n\frac{e^{p_ix}+e^{-p_ix}}{2}
\]

设它们的\(OGF\)分别为\(h,f,g\),则:

\[h(x)*g(x)=f(x)\\
h(x)=\frac{f(x)}{g(x)}
\]

下面考虑求\(OGF\)。

我们将\(F\)换一种写法:

\[F(x)=\sum_{i=-P}^Pa_ie^{\frac{i}{P}x}\\
\]

则:

\[f(x)=\sum_{i=-P}^Pa_i(\sum_{j=0}^{\infty}(\frac{i}{P})^jx^j)\\
=\sum_{i=-P}^Pa_i\frac{1}{1-\frac{i}{P}x}
\]

答案为\(h'(1)\)(带入一下就知道了):

\[h'(x)=\frac{f'(x)*g(x)-f(x)*g'(x)}{g^2(x)}
\]

但是带入\(x=1\)时\(f(x)\)和\(g(x)\)不收敛,于是考虑\(f(x)\)与\(g(x)\)同时乘上\(\prod_{i}(1-\frac{i}{P}x)\)。此时

\[f(x)=\sum_ia_i\prod_{j\neq i}(1-\frac{j}{P}x)
\]

容易得到:

\[f(1)=a_P\prod_{j\neq P}(1-\frac{j}{P})
\]

接下来我们要求\(f'(1)\)。首先我们要利用下面的公式:

\[(\prod_i (1+a_ix))'=\sum_ia_i\prod_{j\neq i}(1+a_jx)
\]

证明的话可以将左边部分暴力展开,求导,就会发现等于右边的部分。

对\(f(x)\)求导的话可以分为两部分:

1.首先是\(i\neq P\)的部分:

\[A(x)=\sum_{i\neq P}a_i\sum_{k\neq i}(-\frac{k}{P})\prod_{j\neq i,j\neq k}(1-\frac{j}{P}x)
\]

因为我最后要的是\(f'(1)\)啊,所以将\(x=1\)带入就会发现,当\(k\neq P\)的时候后面的\(\prod_{j\neq i,j\neq k}(1-\frac{j}{P}x)=0\)。所以:

\[A(1)=-\sum_{i\neq P}a_i\prod_{j\neq i,j\neq P}(1-\frac{j}{P})
\]

2.然后是\(i=P\)的部分:

\[B(1)=a_p\sum_{i\neq P}(-\frac{i}{P}) \prod_{j\neq P,j\neq i}(1-\frac{j}{P})
\]

\(\\\)

于是

\[f'(1)=A(1)+B(1)\\
=-\prod_{i\neq P}(1-\frac{i}{P})(\sum_{j\neq P}\frac{a_j}{1-\frac{j}{P}}+a_P\sum_{j\neq P}\frac{\frac{j}{P}}{1-\frac{j}{P}})
\]

带入\(h'(1)=\frac{f'(1)g(1)-f(1)g'(1)}{g^2(1)}\)就可以了。

设\(f(x)=\sum a_i \prod_{j\neq i}(1-\frac{j}{P}x),g(x)=\sum b_i \prod_{j\neq i}(1-\frac{j}{P}x)\):

又因为\(a_P=b_P=\frac{1}{2^n}\),所以

\[Ans=2^n\sum_{i\neq P}\frac{b_i-a_i}{1-\frac{i}{P}}
\]

下面考虑计算\(a_i,b_i\)。

以\(G(x)\)为例:

\[\prod_i\frac{e^{\frac{p_i}{P}x}+e^{-\frac{p_i}{P}x}}{2}=\sum_{i=-P}^P b_ie^{\frac{i}{P}x}
\]

可以发现这就是个背包。

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 50005 using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;} const ll mod=998244353;
ll ksm(ll t,ll x) {
ll ans=1;
for(;x;x>>=1,t=t*t%mod)
if(x&1) ans=ans*t%mod;
return ans;
} int n;
ll sum,invs;
int s[N],p[N];
ll f[N<<1],g[N<<1];
ll tem[N<<1];
const ll inv2=mod+1>>1; int main() {
n=Get();
for(int i=1;i<=n;i++) s[i]=Get();
for(int i=1;i<=n;i++) p[i]=Get();
f[N]=g[N]=1;
for(int i=1;i<=n;i++) {
sum+=p[i];
ll flag=s[i]?mod-inv2:inv2;
memset(tem,0,sizeof(tem));
for(int j=sum;j>=p[i]-sum;j--) tem[N+j]=f[N+j-p[i]]*inv2%mod;
for(int j=-sum;j<=sum-p[i];j++) (tem[N+j]+=f[N+j+p[i]]*flag)%=mod;
memcpy(f,tem,sizeof(f));
memset(tem,0,sizeof(tem));
for(int j=sum;j>=p[i]-sum;j--) tem[N+j]=g[N+j-p[i]]*inv2%mod;
for(int j=-sum;j<=sum-p[i];j++) (tem[N+j]+=g[N+j+p[i]]*inv2)%=mod;
memcpy(g,tem,sizeof(g));
}
ll ans=0;
for(int i=-sum;i<sum;i++) (ans+=sum*ksm(sum-i,mod-2)%mod*(mod-f[N+i]+g[N+i]))%=mod;
cout<<ans*ksm(2,n)%mod;
return 0;
}

Loj #3045. 「ZJOI2019」开关的更多相关文章

  1. Loj #3044. 「ZJOI2019」Minimax 搜索

    Loj #3044. 「ZJOI2019」Minimax 搜索 题目描述 九条可怜是一个喜欢玩游戏的女孩子.为了增强自己的游戏水平,她想要用理论的武器武装自己.这道题和著名的 Minimax 搜索有关 ...

  2. Loj #3042. 「ZJOI2019」麻将

    Loj #3042. 「ZJOI2019」麻将 题目描述 九条可怜是一个热爱打麻将的女孩子.因此她出了一道和麻将相关的题目,希望这题不会让你对麻将的热爱消失殆尽. 今天,可怜想要打麻将,但是她的朋友们 ...

  3. LOJ 3045: 洛谷 P5326: 「ZJOI2019」开关

    题目传送门:LOJ #3045. 题意简述 略. 题解 从高斯消元出发好像需要一些集合幂级数的知识,就不从这个角度思考了. 令 \(\displaystyle \dot p = \sum_{i = 1 ...

  4. 「ZJOI2019」开关

    传送门 Description 有一些一开始全都是关的开关,每次随机选择一个(每个开关概率不同)开关并改变它的状态,问达到目标状态的期望步数 Solution  \(P=\sum_{i=1}^{n}p ...

  5. 【线段树 树链剖分 差分 经典技巧】loj#3046. 「ZJOI2019」语言【未完】

    还是来致敬一下那过往吧 题目分析 先丢代码 #include<bits/stdc++.h> ; ; ; struct node { int top,son,fa,tot; }a[maxn] ...

  6. @loj - 3043@「ZJOI2019」线段树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 九条可怜是一个喜欢数据结构的女孩子,在常见的数据结构中,可怜最喜 ...

  7. @loj - 3046@「ZJOI2019」语言

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 九条可怜是一个喜欢规律的女孩子.按照规律,第二题应该是一道和数据 ...

  8. 【LOJ】#3046. 「ZJOI2019」语言

    LOJ#3046. 「ZJOI2019」语言 先orz zsy吧 有一个\(n\log^3n\)的做法是把树链剖分后,形成logn个区间,这些区间两两搭配可以获得一个矩形,求矩形面积并 然后就是对于一 ...

  9. 【LOJ】#3044. 「ZJOI2019」Minimax 搜索

    LOJ#3044. 「ZJOI2019」Minimax 搜索 一个菜鸡的50pts暴力 设\(dp[u][j]\)表示\(u\)用\(j\)次操作能使得\(u\)的大小改变的方案数 设每个点的初始答案 ...

随机推荐

  1. Spring-AOP源码分析随手记(二)

    这次来分析下切面的执行过程. 1.怎么看? 怎么开始看源码呢?就直接从被增强的方法调用那里打断点,看看怎么执行的: 然后就来到了这: 2.初步分析 里面有段: if (this.advised.exp ...

  2. SQL Server中使用SQL语句关闭数据库连接和删除数据库文件

    有时候我们想用DROP DATABASE语句删除数据库和数据库文件,会删不掉,因为有其他人正在使用要删除的数据库,这里有一个方法可以强制断开其它数据库连接,再删除数据库. 假如我们要删除的数据库是[T ...

  3. ASP.NET MVC过滤器学习笔记

    1.过滤器的两个特征 1.他是一种特性,可以引用到控制器类和Action方法上.比如下图 这里控制器类和action方法都引用了过滤器,这个过滤器是用来做授权的 2.特征继承自FilterAttrib ...

  4. centos 安装多实例数据库

    在Centos下安装多个MySql 5.7① 下载MySql 解压版安装包② 编写安装脚本③ 将脚本和安装包放置同一目录④ 编写my.cnf文件并放置在/etc/ 目录下⑤ 赋予脚本运行权限并运行⑥ ...

  5. 绕过基于签名的XSS筛选器:修改HTML

    绕过基于签名的XSS筛选器:修改HTML 在很多情况下,您可能会发现基于签名的过滤器只需切换到一个不太熟悉的执行脚本的方法即可.如果失败了,您需要查看混淆攻击的方法. 本文提供了HTML语法可以被混淆 ...

  6. maven 学习---Maven依赖机制

    在 Maven 依赖机制的帮助下自动下载所有必需的依赖库,并保持版本升级. 案例分析 让我们看一个案例研究,以了解它是如何工作的.假设你想使用 Log4j 作为项目的日志.这里你要做什么? 1.在传统 ...

  7. 静态文件 static

    一.常见的形式 前面初步搭建Django开局时候就 在 项目路径下 建立了statics 文件夹,然后在 settings.py  文件的末尾添加了 statics 文件夹的绝对路径. # 这个可以给 ...

  8. Bayesian Optimization使用Hyperopt进行参数调优

    超参数优化 Bayesian Optimization使用Hyperopt进行参数调优 1. 前言 本文将介绍一种快速有效的方法用于实现机器学习模型的调参.有两种常用的调参方法:网格搜索和随机搜索.每 ...

  9. 201871010109-胡欢欢《面向对象程序设计(java)》第十三周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  10. MySQL 数据库 查询语句的基本操作,单表查询,多表查询

    1.查询语句的基本操作 - select - from - where - group by - having - distinct - order by - limit - 聚合函数: count, ...