BZOJ5340 [Ctsc2018]假面 【概率dp】
题目链接
题解
我们能很容易维护每个人当前各种血量的概率
设\(p[u][i]\)表示\(u\)号人血量为\(i\)的概率
每次攻击的时候,讨论一下击中不击中即可转移
是\(O(Qm^2)\)的
现在考虑一下结界
如果我们设\(f[u][i]\)表示除了\(u\)还存活\(i\)个人的概率
那么
\]
所以我们只需计算\(f[u][i]\)
\(f[u][i]\)同样可以通过枚举剩余每个人存活与否进行转移,是\(O(n^3)\)的,复杂度过高
我们考虑计算\(g[i]\)表示剩余\(i\)人的概率
枚举\(u\)
\]
即可\(O(n^2)\)计算\(g[i]\)
如果我们拿\(f[u][i]\)来计算\(g[i]\)的话
\]
那么
\]
也可以\(O(n^2)\)递推
这样我们就做完了
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 205,maxm = 105,INF = 1000000000,P = 998244353;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
LL p[maxn][maxm],f[maxn][maxn],g[maxn][maxn],n,m[maxn],id[maxn];
LL INV[maxn];
inline LL qpow(LL a,LL b){
LL ans = 1;
for (; b; b >>= 1,a = 1ll * a * a % P)
if (b & 1) ans = 1ll * ans * a % P;
return ans;
}
inline LL inv(int x){
if (x <= n) return INV[x];
return qpow(x,P - 2);
}
int main(){
n = read();
REP(i,n) m[i] = read(),p[i][m[i]] = 1;
INV[0] = 1; INV[1] = 1;
for (int i = 2; i <= n; i++) INV[i] = 1ll * (P - P / i) * INV[P % i] % P;
LL Q = read(),opt,u,v,pp,x,k;
while (Q--){
opt = read();
if (!opt){
x = read(); u = read(); v = read(); pp = u * inv(v) % P;
p[x][0] = (p[x][0] + pp * p[x][1] % P) % P;
for (int i = 1; i <= m[x]; i++)
p[x][i] = ((p[x][i] * (1 - pp) % P + p[x][i + 1] * pp % P) % P + P) % P;
}
else {
k = read();
cls(g); g[0][0] = 1;
for (int i = 1; i <= k; i++){
u = id[i] = read();
g[i][0] = g[i - 1][0] * p[u][0] % P;
for (int j = 1; j <= i; j++){
g[i][j] = ((g[i - 1][j] * p[u][0] % P + g[i - 1][j - 1] * (1 - p[u][0]) % P) % P + P) % P;
}
}
for (int i = 1; i <= k; i++){
u = id[i];
LL ans = 0,Inv = inv(p[u][0]);
if (!p[u][0]){
for (int j = 0; j < k; j++)
f[u][j] = g[k][j + 1];
}
else {
f[u][0] = 1ll * g[k][0] * Inv % P;
for (int j = 1; j < k; j++){
f[u][j] = (1ll * (g[k][j] - 1ll * f[u][j - 1] * (1 - p[u][0]) % P) % P * Inv % P + P) % P;
}
}
for (int j = 0; j < k; j++){
ans = (ans + 1ll * f[u][j] * inv(j + 1) % P) % P;
}
ans = (1ll * ans * (1ll - p[u][0]) % P + P) % P;
printf("%lld",ans);
if (i < k) putchar(' ');
else puts("");
}
}
}
for (int i = 1; i <= n; i++){
LL ans = 0;
for (int j = 1; j <= m[i]; j++)
ans = (ans + 1ll * j * p[i][j] % P) % P;
printf("%lld",ans);
if (i < n) putchar(' ');
else puts("");
}
return 0;
}
BZOJ5340 [Ctsc2018]假面 【概率dp】的更多相关文章
- [CTSC2018]假面(概率DP)
考场上以为CTSC的概率期望题都不可做,连暴力都没写直接爆零. 结果出来发现全场70以上,大部分AC,少于70的好像极少,感觉血亏. 设a[i][j]表示到当前为止第i个人的血量为j的概率(注意特判血 ...
- BZOJ5340: [Ctsc2018]假面
BZOJ5340: [Ctsc2018]假面 https://lydsy.com/JudgeOnline/problem.php?id=5340 分析: 背包,只需要求\(g_{i,j}\)表示强制活 ...
- BZOJ5340: [Ctsc2018]假面【概率+期望】【思维】
LINK 思路 首先考虑减血,直接一个dp做过去,这个部分分不难拿 然后是\(op=1\)的部分 首先因为要知道每个人被打的概率,所以需要算出这个人活着的时候有多少个人活着时概率是什么 那么用\(g_ ...
- [CTSC2018] 假面 | 期望 DP
题目链接 LOJ 2552 Luogu P4564 考场上这道题我先是写了个70分暴力,然后发现似乎可以NTT,然鹅问题是--我没学过NTT,遂脑补之,脑补出来了,下午出成绩一看,卡成暴力分(70)- ...
- Codeforces 28C [概率DP]
/* 大连热身D题 题意: 有n个人,m个浴室每个浴室有ai个喷头,每个人等概率得选择一个浴室. 每个浴室的人都在喷头前边排队,而且每个浴室内保证大家都尽可能均匀得在喷头后边排队. 求所有浴室中最长队 ...
- HDU 4405 Aeroplane chess (概率DP)
题意:你从0开始,要跳到 n 这个位置,如果当前位置是一个飞行点,那么可以跳过去,要不然就只能掷骰子,问你要掷的次数数学期望,到达或者超过n. 析:概率DP,dp[i] 表示从 i 这个位置到达 n ...
- POJ 2096 Collecting Bugs (概率DP)
题意:给定 n 类bug,和 s 个子系统,每天可以找出一个bug,求找出 n 类型的bug,并且 s 个都至少有一个的期望是多少. 析:应该是一个很简单的概率DP,dp[i][j] 表示已经从 j ...
- POJ 2151 Check the difficulty of problems (概率DP)
题意:ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 ,求每队至少解出一题且冠军队至少解出N道题的概率. 析:概率DP,dp[i][j][k] 表示第 i 个队伍,前 j 个题,解出 ...
- 概率DP light oj 1030
t组数据 n块黄金 到这里就捡起来 出发点1 到n结束 点+位置>n 重掷一次 dp[i] 代表到这里的概率 dp[i]=(dp[i-1]+dp[i-2]... )/6 如果满6个的话 否则 ...
随机推荐
- MySQL数据表操作(DDL)
一.创建数据表 语法:create table 表名称(字段 字段类型 [字段属性],字段 字段类型 [字段属性],...) [表选项]; 表选项:数据表的属性,一般包括engine.charset. ...
- python中使用空格还是使用 Tab键缩进的建议
对于程序员来说,其实Tab和空格远远不只是“立场”问题那么简单. 在不同的编辑器里tab的长度可能不一致,所以在一个编辑器里用tab设置缩进后,在其它编辑器里看可能缩进就乱了.空格不会出现这个问题,因 ...
- 小程序开发-7-访问api数据与ES6在小程序中的应用
访问API数据与ES6在小程序中的应用 看待组件的两种观点 组件复用 代码分离-(特别重要) 不能在一个页面写所有的代码,代码分离具有很强的可读性.可维护性 Blink Api 介绍与测试API ur ...
- java图片识别 [Tesseract-OCR]
以下链接包含,安装包及程序运行需要的jar 包,中文资源包. 中文包使用方式:找到tessdata安装目录(我本地:C:\Program Files (x86)\Tesseract-OCR\tessd ...
- PHP.45-TP框架商城应用实例-后台20-权限管理-RBAC表构造与代码生成
权限管理 三张主表{p39_privilege(权限).p39_role(角色).p39_admin(管理)} 两张中间表{p39_role_pri(角色-权限).p39_admin_role(管理- ...
- OpenCV代码提取:transpose函数的实现
OpenCV中的transpose函数实现图像转置,公式为: 目前fbc_cv库中也实现了transpose函数,支持多通道,uchar和float两种数据类型,经测试,与OpenCV3.1结果完全一 ...
- 2007: [Noi2010]海拔
2007: [Noi2010]海拔 https://www.lydsy.com/JudgeOnline/problem.php?id=2007 分析: 平面图最小割. S在左下,T在右上,从S到T的一 ...
- kill -9 vs killall
kill Linux中的kill命令用来终止指定的进程(terminate a process)的运行,是Linux下进程管理的常用命令.通常,终止一个前台进程可以使用Ctrl+C键,但是,对于一个后 ...
- leetcode笔记--2 reverse string
my answer: 出错点:new_list[s] = list_s[u-1-s] 这样会出错, 重点:(1) map(str, s) 函数的使用,例:ls = [1,2,3]rs = map(st ...
- Django笔记 —— Admin(Django站点管理界面)
最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...