题目大意

有\(n\)(\(n\leq200\))个非负整数\(m_1,m_2,...,m_n\)(\(\forall i\in[1,n],m_i\leq100\)),有\(q\)(\(q\leq2*10^5\))个操作,每个操作是以下两种之一:

(1)给出位置\(x\),概率\(q\),若\(m_x\)大于0,则有\(q\)的概率将\(m_x\)减一;若\(m_x\)为0,则不进行任何操作

(2)给出一个数\(k\)和\(k\)个不重复的位置\(d_1,d_2,...d_k\),在\(m_{d_1},...,m_{d_k}\)中随机选一个正数,求选中位置\(d_1,...,d_k\)的概率各是多少,这种操作不超过1000个

最后输出每个位置上的数在经过\(q\)个操作后期望分别是多少。

题解

设\(p_{i,j}\)表示现在第\(i\)个数还剩\(j\)的概率是多少

在进行操作前,\(p_{i,m_i}=1\),其他的\(p_{i,j}\)都为0

如果是操作(1),\(x\)有\(q\)的概率减一,也就是说,\(p_{x,j}\)有\(q\)的概率转移到\(p_{x,j-1}\),\(p_{x,j}\)有\(1-q\)的概率转移到\(p_{x,j}\),特殊地,\(p_{x,0}\)有\(1\)的概率转移到\(p_{x,0}\)

如果是操作(2),设\(g_{i,j}\)表示在不考虑\(d_i\)时,有\(j\)个数是正数的概率,那么\(d_i\)是正数且被选中的概率就是$$(1-p_{d_i,0})(\sum_{j=0}^{k-1}g_{i,j}\frac{1}{k+1})$$这样,在已知\(g\)的情况下,就可以在\(\Theta(k^2)\)的时间内求出一次(2)操作的答案了

那么\(g\)该怎么求呢?设\(f_{i,j}\)表示考虑位置\(d_1,...,d_i\)位置上的数,其中正数有\(j\)个

初始\(f_{0,0}=1\),转移为$$ f_{i,j} \begin{cases} f_{i-1,j-1}(1-p_{d_i,0})+f_{i-1,j}p_{d_i,0} & \text {j>0} \ f_{i-1,j}*p_{d_i,0} & \text{j=0} \end{cases} $$

这样就能求出在这\(k\)个位置中,有\(j\)个位置上的数是正数的概率了,但是该如何把这个某个位置上的数的影响去掉,求出\(g\)呢?

重新dp一遍想必是不可能的,那样对于每个\(d_i\)都要重新进行\(\Theta(k^2)\)的dp,一次(2)操作就是\(\Theta(k^3)\),时间超限了

能否用\(f\)和\(p\)进行一些变化求出\(p\)呢?会发现在已知\(f_{i+1,0},...,f_{i+1,k}\)和\(p_{d_{i+1},0}\)时,是可以求出\(f_{i,0},...,f_{i,k}\)的

先把推出\(f_{i+1,0},...,f_{i+1,k}\)的所有式子写出来:

\(f_{i+1,0}= f_{i,0}*p_{d_{i+1},0}\)

\(f_{i+1,1}= f_{i,0}*(1-p_{d_{i+1},0})+f_{i,1}*p_{d_{i+1},0}\)

\(...\)

\(f_{i+1,k}= f_{i,k-1}*(1-p_{d_{i+1},0})+f_{i,k}*p_{d_{i+1},0}\)

再把\(f_{i,0},...,f_{i,k}\)拿到左边:

\(f_{i,0}= \frac{f_{i+1,0}}{p_{d_{i+1},0}}\)

\(f_{i,1}= \frac{f_{i+1,1}-f_{i,0}*(1-p_{d_{i+1},0})}{p_{d_{i+1},0}}\)

\(...\)

\(f_{i,k}= \frac{f_{i+1,k}-f_{i,k-1}*(1-p_{d_{i+1},0})}{p_{d_{i+1},0}}\)

特殊地,当\(p_{d_{i+1},0}=0\)时,\(f_{i,j}=f_{i+1,j+1}\)

这个变化的复杂度是\(\Theta(k)\)的

\(f_{i+1,...}\)本来是\(d_1,..,d_{i+1}\)的答案,经过变化后,\(f_{i,...}\)是\(d_1,..,d_{i}\)的答案,这相当于把\(d_{i+1}\)位置上的数的影响从\(f_{i+1,...}\)中去掉

那么\(g_{i,...}\)可以看成把\(d_i\)位置上的数的影响从\(f_{n,...}\)中删去,就可以进行相似的变化

当\(p_{d_{i+1},0}\neq 0\)时,

\(g_{i,0}= \frac{f_{n,0}}{p_{d_{i+1},0}}\)

\(g_{i,1}= \frac{f_{n,1}-g_{i,0}*(1-p_{d_{i+1},0})}{p_{d_{i+1},0}}\)

\(...\)

\(g_{i,k}= \frac{f_{n,k}-g_{i,k-1}*(1-p_{d_{i+1},0})}{p_{d_{i+1},0}}\)

当\(p_{d_{i+1},0}=0\)时,\(g_{i,j}=f_{g,j+1}\)

代码
#include<algorithm>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define maxn 210
#define maxm 110
#define LL long long
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(int x)
{
if(x==0){putchar('0');return;}
int f=0;char ch[20];
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
return;
}
const LL mod=998244353;
int inv[maxn],n,q,m[maxn],p[maxn][maxm],f[2][maxn],g[maxn],id[maxn],yes[maxn],no[maxn],num;
int qp(int x,int y){int ans=1;while(y){if(y&1)ans=(LL)ans*(LL)x%mod;x=(LL)x*(LL)x%mod,y>>=1;}return ans;}
void work()
{
rep(i,1,num)f[0][i]=0;f[0][0]=1;
rep(i,0,num-1)
{
int now=i&1,nxt=now^1;
rep(j,0,i)
{
f[nxt][j+1]=((LL)f[nxt][j+1]+(LL)f[now][j]*(LL)yes[i+1]%mod)%mod;
f[nxt][j]=((LL)f[nxt][j]+(LL)f[now][j]*(LL)no[i+1]%mod)%mod;
f[now][j]=0;
}
}
rep(i,1,num)
{
int res=0,fdie=qp(no[i],mod-2);
if(no[i]!=0)
{
g[0]=(LL)f[num&1][0]*(LL)fdie%mod;
rep(j,1,num-1)g[j]=(f[num&1][j]-(LL)g[j-1]*(LL)yes[i]%mod+mod)%mod*(LL)fdie%mod;
}
else
{
rep(j,0,num-1)g[j]=f[num&1][j+1];
}
rep(j,0,num-1)res=(res+(LL)yes[i]*(LL)g[j]%mod*(LL)inv[j+1]%mod)%mod;
write(res);
if(i!=num)putchar(' ');
}
rep(i,0,num)f[num&1][i]=0;
putchar('\n');
}
int main()
{
n=read();
rep(i,1,n)m[i]=read(),p[i][m[i]]=1,inv[i]=qp(i,mod-2);
q=read();
while(q--)
{
int op=read();
if(op)
{
num=read();
rep(i,1,num)id[i]=read();
rep(i,1,num)no[i]=p[id[i]][0],yes[i]=(1-p[id[i]][0]+mod)%mod;
work();
}
else
{
int x=read(),u=read(),v=read(),die=(LL)u*(LL)qp(v,mod-2)%mod,live=(LL)(v-u)%mod*(LL)qp(v,mod-2)%mod;
rep(i,1,m[x])p[x][i-1]=(p[x][i-1]+(LL)p[x][i]*(LL)die%mod)%mod,p[x][i]=(LL)p[x][i]*(LL)live%mod;
}
}
rep(i,1,n)
{
int res=0;
rep(j,1,m[i])res=(res+(LL)j*(LL)p[i][j]%mod)%mod;
write(res);
if(i!=n)putchar(' ');
}
return 0;
}
一些意见

第一次见需要对dp结果去掉一个决策的影响的题

以及今天学会设置友链了!

并不对劲的bzoj5340:loj2552:uoj399:p4564: [Ctsc2018]假面的更多相关文章

  1. 洛谷 P4564 [CTSC2018]假面(期望+dp)

    题目传送门 题意: 有 \(n\) 个怪物,第 \(i\) 个怪物初始血量为 \(m_i\).有 \(Q\) 次操作: 0 x u v,有 \(p=\frac{u}{v}\) 的概率令 \(m_x\) ...

  2. BZOJ5340: [Ctsc2018]假面

    BZOJ5340: [Ctsc2018]假面 https://lydsy.com/JudgeOnline/problem.php?id=5340 分析: 背包,只需要求\(g_{i,j}\)表示强制活 ...

  3. BZOJ5340 & 洛谷4564 & LOJ2552:[CTSC2018]假面——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5340 https://www.luogu.org/problemnew/show/P4564 ht ...

  4. BZOJ5340 [Ctsc2018]假面 【概率dp】

    题目链接 BZOJ5340 题解 我们能很容易维护每个人当前各种血量的概率 设\(p[u][i]\)表示\(u\)号人血量为\(i\)的概率 每次攻击的时候,讨论一下击中不击中即可转移 是\(O(Qm ...

  5. BZOJ5340: [Ctsc2018]假面【概率+期望】【思维】

    LINK 思路 首先考虑减血,直接一个dp做过去,这个部分分不难拿 然后是\(op=1\)的部分 首先因为要知道每个人被打的概率,所以需要算出这个人活着的时候有多少个人活着时概率是什么 那么用\(g_ ...

  6. 并不对劲的bzoj5341:loj2553:uoj400:p4565:[Ctsc2018]暴力写挂

    题目大意 有两棵\(n\)(\(n\leq366666\))个节点的树,\(T\)和\(T'\),有边权 \(dep(i)\)表示在\(T\)中\(i\)号点到\(1\)号点的距离,\(dep'(i) ...

  7. 并不对劲的bzoj5342:loj2554:uoj401:p4566: [Ctsc2018]青蕈领主

    题目大意 \(T\)(\(T\leq100\))组询问 有\(1\)到\(n\)(\(n\leq50000\))这\(n\)个整数组成的一个排列 定义这个排列的一个子区间是"连续" ...

  8. UOJ399 CTSC2018 假面 期望、DP

    传送门 \(Q \leq 200000 , C \leq 1000 , m_i \leq 100\)-- 先考虑如何维护最后一次操作时所有人的血量期望.不难发现我们需要的复杂度是\(O(Qm_i)\) ...

  9. 【loj2552】【CTSC2018】假面

    题目 有\(n\)个敌方单位,初始生命值分别为\(m_1,\cdots,m_n\) : 假面可以释放\(Q\)个技能: $op = 0  ,  id , u , v $ 表示对\(id\)号敌人有\( ...

随机推荐

  1. 【CSS】position relative 用法

    Relative是position的一个属性,是相对定位. position的默认值是static,(也就是说对于任意一个元素,如果没有定义它的position属性,那么它的position:stat ...

  2. 80. Hibernate 5.0命名策略使用naming-strategy 不起作用【从零开始学Spring Boot】

    [原创文章,转载请注明出处] 事情的起因:一不小心从1.3.3升级到了1.4.0版本,结果就碰到了各种悲催的事情了,好吧,Hibernate5.0的新特性就是其中一个坑,我们会发现我们配置的namin ...

  3. HDU1213最简单的并查集问题

    题目地址 http://acm.hdu.edu.cn/showproblem.php?pid=1213 #include<iostream> using namespace std; #d ...

  4. UVA11090 Going in Cycle!! 【SPFA】

    题意:求一个无向图的边权平均值最小的环 思路:假设环中Σwi/t<ans 那变形一下就是Σwi<ans*t → Σ(wi-ans)< 0 这样就可以二分答案做了 #include & ...

  5. BZOJ 2763: [JLOI2011]飞行路线 【SPFA】

    Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格.Al ...

  6. poj3207:Ikki's Story IV-Panda's Trick【2-sat tarjan】

    题目大意:圆盘上顺次安放0, 1, 2, …, n – 1的点,每次给出两个点需要连边,可以选择在圆盘的正面连边或在圆盘的反面连边,问是否存在一种方案使得所有连线不相交? 思路:本问题可以等价成:圆盘 ...

  7. [NOIP2000] 提高组 洛谷P1023 税收与补贴问题

    题目背景 每样商品的价格越低,其销量就会相应增大.现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),并假设相邻价位间销量的变化是线性的且在价格高于给定的最高价位后,销量以某固定数值递 ...

  8. PHP的资源类型

    PHP的资源类型 php的资源类型 常见的有:打开文件.数据库连接.图形画布等. 常用操作:创建.使用.释放. 以文件操作为示例: //文件路径 $file_url = './data.txt'; / ...

  9. Memcached Redis相关的干货

    为了以后查阅方便,所以转了各位的博文,感谢各位原博主. http://www.searchtb.com/2011/05/redis-storage.html           redis内存存储结构 ...

  10. Swift--Set的了解

    1. 创建和初始化一个空的set var letters = Set<Character>() 或者,如果上下文已经提供了类型信息,例如函数参数或已输入的变量或常量,则可以创建空的集合,其 ...