P4564 [CTSC2018]假面(期望)

P4564 [CTSC2018]假面

首先容易看出结界技能对第二问敌方剩余生命值期望没有影响。

如何求出第iii个人的剩余生命值期望?
只需要根据Ei=∑j=0aij×fi,jE_i=\sum_{j=0}^{a_i}j×f_{i,j}Ei=j=0aij×fi,j
预处理fi,jf_{i,j}fi,j:第iii个人的剩余生命值为jjj的期望(aia_iai表示最初生命值)

由于每次锁定技能只能明确对一名地方单位造成攻击(ppp概率击中而qqq概率不中),每次只需要O(ai)O(a_i)O(ai)的代价维护fi,jf_{i,j}fi,j总的时间复杂度O(Qm)O(Qm)O(Qm)
转移方程:fi,j=pfi,j+1+qfi,jf_{i,j}=pf_{i,j+1}+qf_{i,j}fi,j=pfi,j+1+qfi,j,注意fi,0=pfi,1+fi,0f_{i,0}=pf_{i,1}+f_{i,0}fi,0=pfi,1+fi,0


对于第二个技能,想要知道命中uuu的概率,我们需要知道除了u之外还有jjj个人存活下,不妨叫做gu,jg_{u,j}gu,j

只需要把除了uuu的其他敌人vvv拿出来跑一遍背包即可(注意逆序)
gu,j=alivev×gu,j−1+deadv×gu,jg_{u,j}=\text{alive}_v×g_{u,j-1}+\text{dead}_v×g_{u,j}gu,j=alivev×gu,j1+deadv×gu,j

显然alivev=1−fv,0\text{alive}_v=1-f_{v,0}alivev=1fv,0:v存活下来的概率,deadv=fv,0\text{dead}_v=f_{v,0}deadv=fv,0死了的概率。

对于第二个技能范围的每个敌人,我们都需要预处理一下gu,jg_{u,j}gu,j数组,也就是O(n3)O(n^3)O(n3)的复杂度,第二个技能总时间复杂度O(Cn3)O(Cn^3)O(Cn3),代码如下这时候我们能够拿到707070pts,O(Qm+Cn3)O(Qm+Cn^3)O(Qm+Cn3)

#include<cstring>
#include<iostream>
using namespace std;
using ll=long long;
constexpr ll mod=998244353;
ll qmi(ll a,ll b)
{ll res=1;while(b){if(b&1) res=res*a%mod;a=a*a%mod;b>>=1;}return res;
}
ll inv[205],a[205],b[205];
ll f[205][105];//f[i][j]第i个人还有j滴血的概率
ll g[205];//将u那一维压缩了
int n,m;
void attack(int i,ll p)//O(qc)
{ll q=(1-p+mod)%mod;for(int j=0;j<=a[i];j++){if(j)f[i][j]=(p*f[i][j+1]%mod+q*f[i][j]%mod)%mod;elsef[i][j]=(p*f[i][j+1]%mod+f[i][j])%mod;}
}
void solve(int k)//O(n^3)
{for(int u=1;u<=k;u++)//枚举范围呢的每一个敌人{memset(g,0,sizeof g);g[0]=1ll;for(int i=1;i<=k;i++)//除了u的敌人跑一边背包{if(u==i) continue;ll alive=((1ll-f[b[i]][0])%mod+mod)%mod;ll dead=((1ll-alive)%mod+mod)%mod;for(int j=i;j>=0;j--)//逆序!{if(j) g[j]=(g[j]*dead+g[j-1]*alive%mod)%mod;else g[j]=g[j]*dead%mod;}}ll ans=0;for(int j=0;j<k;j++) ans=(ans+g[j]*inv[j+1]%mod)%mod;ans=ans*((1ll-f[b[u]][0])%mod+mod)%mod;cout<<ans<<' ';}cout<<'\n';
}
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);cin>>n;for(int i=1;i<=n;i++){cin>>a[i];inv[i]=qmi(i,mod-2);f[i][a[i]]=1;}cin>>m;while(m--){int op;cin>>op;if(op==0){int id;ll u,v;cin>>id>>u>>v;attack(id,1ll*u*qmi(v,mod-2)%mod);}else{int k;cin>>k;for(int i=1;i<=k;i++) cin>>b[i];solve(k);}}for(int i=1;i<=n;i++){ll ans=0;for(int j=1;j<=a[i];j++)ans=(ans+j*f[i][j]%mod)%mod;cout<<ans<<' ';}return 0;
}

考虑优化,显然我们TLE是由于第二个操作,如果每次枚举然后跑背包似乎有些冗余。我们另设gjg_jgj表示jjj个人或者的概率,而用hu,jh_{u,j}hu,j表示除了u之外还有jjj个人存活下(也就是上面的gu,jg_{u,j}gu,j)有下面递推
gj=aliveu×hu,j−1+deadu×hu,jg_j=\text{alive}_u×h_{u,j-1}+\text{dead}_u×h_{u,j}gj=aliveu×hu,j1+deadu×hu,j
于是有hu,j=gj−aliveu×hu,j−1deaduh_{u,j}=\frac{g_j-\text{alive}_u×h_{u,j-1}}{\text{dead}_u}hu,j=deadugjaliveu×hu,j1
于是我们只需要O(n2)O(n^2)O(n2)预处理gjg_jgj,然后枚举uuu线性求出hu,jh_{u,j}hu,j同样时间复杂度O(n2)O(n^2)O(n2),那么技能二时间复杂度O(Cn2)O(Cn^2)O(Cn2)

注意gj=aliveu×hu,j−1,deadu=0g_j=\text{alive}_u×h_{u,j-1},\text{dead}_u=0gj=aliveu×hu,j1,deadu=0
即存在hu,j=gj+1h_{u,j}=g_{j+1}hu,j=gj+1

总时间复杂度O(Qm+Cn2)O(Qm+Cn^2)O(Qm+Cn2)

#include<cstring>
#include<iostream>
using namespace std;
using ll=long long;
constexpr ll mod=998244353;
ll qmi(ll a,ll b)
{ll res=1;while(b){if(b&1) res=res*a%mod;a=a*a%mod;b>>=1;}return res;
}
ll inv[205],a[205],b[205];
ll f[205][105];
ll g[205],h[205];//h同样可以少一维
int n,m;
void attack(int i,ll p)//O(qc)
{ll q=(1-p+mod)%mod;for(int j=0;j<=a[i];j++){if(j)f[i][j]=(p*f[i][j+1]%mod+q*f[i][j]%mod)%mod;elsef[i][j]=(p*f[i][j+1]%mod+f[i][j])%mod;}
}
void solve(int k)
{memset(g,0,sizeof g);g[0]=1ll;for(int i=1;i<=k;i++)//预处理 g{ll alive=((1ll-f[b[i]][0])%mod+mod)%mod;ll dead=((1ll-alive)%mod+mod)%mod;for(int j=i;j>=0;j--){if(j) g[j]=(g[j]*dead+g[j-1]*alive%mod)%mod;else g[j]=g[j]*dead%mod;}}for(int u=1;u<=k;u++){ll ans=0;ll alive=((1ll-f[b[u]][0])%mod+mod)%mod;ll dead=((1ll-alive)%mod+mod)%mod;memset(h,0,sizeof h);if(alive!=1)//1-dead != 0{ll invd=qmi(dead,mod-2);h[0]=g[0]*invd%mod;for(int j=1;j<k;j++)h[j]=(g[j]-alive*h[j-1]%mod+mod)%mod*invd%mod;}else//dead=1{for(int j=0;j<=k;j++)h[j]=g[j+1];}for(int j=0;j<k;j++) ans=(ans+h[j]*inv[j+1]%mod)%mod;ans=ans*alive%mod;cout<<ans<<' ';}cout<<'\n';
}
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);cin>>n;for(int i=1;i<=n;i++){cin>>a[i];inv[i]=qmi(i,mod-2);f[i][a[i]]=1;}cin>>m;while(m--){int op;cin>>op;if(op==0){int id;ll u,v;cin>>id>>u>>v;attack(id,1ll*u*qmi(v,mod-2)%mod);}else{int k;cin>>k;for(int i=1;i<=k;i++) cin>>b[i];solve(k);}}for(int i=1;i<=n;i++){ll ans=0;for(int j=1;j<=a[i];j++)ans=(ans+j*f[i][j]%mod)%mod;cout<<ans<<' ';}return 0;
}

要加油哦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318958.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客题霸 [连续子数组的最大和] C++题解/答案

牛客题霸 [连续子数组的最大和] C题解/答案 题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含…

P4234-最小差值生成树【LCT】

正题 题目链接:https://www.luogu.com.cn/problem/P4234 题目大意 给出nnn个点mmm条边的一张图。求一棵生成树使得最大边权减去最小边权最小。 1≤n≤5104,1≤m≤21051\leq n\leq 5\times 10^4,1\leq m\leq 2\times 10^51≤n≤5104,1≤m≤2105 解题思路 按照边权排序&#x…

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

上篇文章【.NET Core项目实战-统一认证平台】第五章 网关篇-自定义缓存Redis 我们介绍了网关使用Redis进行缓存&#xff0c;并介绍了如何进行缓存实现&#xff0c;缓存信息清理接口的使用。本篇我们将介绍如何实现网关自定义客户端授权&#xff0c;实现可以为不同的接入客户端设…

2287. 【POJ Challenge】消失之物(数组递推\分治优化背包)

2287. 【POJ Challenge】消失之物 这题的思想和P4564 [CTSC2018]假面优化的思想一样&#xff0c;应该反过来说&#xff0c;假面那个题应该是借鉴这题的思路。 显然不能枚举每个物品消失O(n)O(n)O(n)&#xff0c;然后跑背包O(nm)O(nm)O(nm) 预处理dp fjf_jfj​表示nnn个物品装…

如何用ABP框架快速完成项目(面向项目交付编程面向客户编程篇) - 广州.net微软技术俱乐部12月份活动报名帖...

这是广州.net微软技术俱乐部12月份活动报名帖。此帖会持续更新。活动课程标题是&#xff1a;如何用ABP框架快速完成项目(面向项目交付编程面向客户编程篇)这是内容大纲&#xff1a;ABP框架简介&#xff08;这里会聊聊.net真的不如JAVA吗&#xff1f;&#xff09;快的定义!用ABP…

P5012-水の数列【并查集,RMQ】

正题 题目链接:https://www.luogu.com.cn/problem/P5012 题目大意 nnn个数字的一个序列&#xff0c;TTT次询问给出[l,r][l,r][l,r]要求 找出一个最大的xxx满足。提出所有的小于xxx的数&#xff0c;然后被提出的数的连续区间长度平方和除以xxx的值最大要求分出来的区间个数在[…

牛客题霸 [ 换钱的最少货币数] C++题解/答案

牛客题霸 [ 换钱的最少货币数] C题解/答案 题目描述 给定数组arr&#xff0c;arr中所有的值都为正整数且不重复。每个值代表一种面值的货币&#xff0c;每种面值的货币可以使用任意张&#xff0c;再给定一个aim&#xff0c;代表要找的钱数&#xff0c;求组成aim的最少货币数。…

codeforces gym100959 I - Robots(稠密图建图优化)

I - Robots 显然可以两点之间能连边就连边&#xff0c;但是边数会很多&#xff0c;考虑优化 对于三个点(x0,y0)(x_0,y_0)(x0​,y0​)&#xff0c;(x0,y1)(x_0,y_1)(x0​,y1​)&#xff0c;(x0,y2)(x_0,y_2)(x0​,y2​) 如果三个点的方向都是UUU 那么没有必要1→31\to 31→3连…

.Net Core微服务系列--开篇

得原来有个项目是用wcf做的分布式&#xff0c;不仅横向根据业务拆分了&#xff0c;纵向把业务处理、数据访问等也拆分了成不同的服务&#xff0c;这个是当时公司的产品我也只是一个小小的开发人员所以就不做太多的评论&#xff0c;只是不得不吐槽下调试真的太麻烦。后来&#x…

牛客题霸 [ 树的直径] C++题解/答案

牛客题霸 [ 树的直径] C题解/答案 题目描述 给定一棵树&#xff0c;求出这棵树的直径&#xff0c;即两个节点距离的最大值。 题解&#xff1a; 不知道大家听没听过一个结论&#xff1a; 树的直径可以通过两边dfs找到 步骤&#xff1a; 1.从任意一点进行dfs&#xff0c;然后…

GDOI2021划水记

Day0 上午有意志行&#xff0c;一大早就醒了&#xff0c;然后走了五个小时脚痛。中午洗澡&#xff0c;宿舍轮流看巨人最终话然后聊了一个小时&#xff1f; 下午老师带着我和全爷先开溜&#xff0c;宿舍好像很破旧还还没得充电&#xff0c;领了牌牌和斐爷去吃饭。 然后六点多和…

codeforces1493 D. GCD of an Array(数论)

昨天晚上用的镜像&#xff0c;看的B的图片瞬间不想写了&#xff08;而且这周作业还没碰&#xff09;&#xff0c;不过看到D题突然想做做&#xff0c;于是有了下面的思路&#xff0c;写了一个小时&#xff0c;写完没交看了下榜单发现C题竟然过的人也不多&#xff0c;看了看C题感…

被低估的.net(中) - 广州.net俱乐部2019年纲领

这是被低估的.net系列的中篇。上篇在这里&#xff1a;被低估的.net(上) - 微软MonkeyFest 2018广州分享会活动回顾中篇本来不是这样的&#xff0c;中篇的草稿大纲其实在写上篇之前就写好了&#xff0c;嗯&#xff0c;当时给张队长看过了。然而却因为被.net 粉丝的热情震惊和感动…

P7518-[省选联考2021A/B卷]宝石【主席树,二分】

正题 题目链接:https://www.luogu.com.cn/problem/P7518 题目大意 给出nnn个点的一棵树&#xff0c;每个点上有不大于mmm的数字。 然后给出一个长度为ccc的各个位数不同的序列&#xff0c;每次询问一条路径上找到一个最大的kkk使得该序列的存在1∼k1\sim k1∼k的子序列。 1≤…

牛客题霸 [ 缺失数字] C++题解/答案

牛客题霸 [ 缺失数字] C题解/答案 题目描述 从0,1,2,…,n这n1个数中选择n个数&#xff0c;找出这n个数中缺失的那个数&#xff0c;要求O(n)尽可能小。 题解&#xff1a; 我们可以用map来标记已出现过的数字 因为数组长度给出是len&#xff0c;因为是连续的数字&#xff0c;…

bzoj 2908. 又是nand(树链剖分+区间NAND+单点修改)

首先考虑问题的简化版 存在下面两个操作 询问[l,r][l,r][l,r]区间与非的值即alNANDal1NAND…NANDara_l \text{NAND} a_{l1} \text{NAND}\dots \text{NAND} a_ral​NANDal1​NAND…NANDar​单线修改p,xp,xp,x即apxa_pxap​x 这是一道去年校赛题最近才发现区间与非的板子题 首…

[译]RabbitMQ教程C#版 - 远程过程调用(RPC)

先决条件本教程假定 RabbitMQ 已经安装&#xff0c;并运行在localhost标准端口&#xff08;5672&#xff09;。如果你使用不同的主机、端口或证书&#xff0c;则需要调整连接设置。从哪里获得帮助如果您在阅读本教程时遇到困难&#xff0c;可以通过邮件列表 联系我们。在第 教程…

P7514-[省选联考2021A/B卷]卡牌游戏【贪心】

正题 题目链接:https://www.luogu.com.cn/problem/P7514 题目大意 给出nnn个卡牌有ai/bia_i/b_iai​/bi​&#xff0c;开始都是aia_iai​朝上&#xff0c;将不超过mmm张卡牌变为bib_ibi​面朝上&#xff0c;使得朝上的数字中最大值减去最小值最小。 3≤n≤106,1≤m<n,1≤a…

牛客题霸 [ 旋转数组] C++题解/答案

牛客题霸 [ 旋转数组] C题解/答案 题目描述 一个数组A中存有N&#xff08;N&gt0&#xff09;个整数&#xff0c;在不允许使用另外数组的前提下&#xff0c;将每个整数循环向右移M&#xff08;M>0&#xff09;个位置&#xff0c;即将A中的数据由&#xff08;A0 A1 ………

ML.NET速览

什么是ML.NET&#xff1f;ML.NET是由微软创建&#xff0c;为.NET开发者准备的开源机器学习框架。它是跨平台的&#xff0c;可以在macOS&#xff0c;Linux及Windows上运行。机器学习管道ML.NET通过管道(pipeline)方式组合机器学习过程。整个管道分为以下四个部分&#xff1a;Loa…