Solution -「CTSC 2017」「洛谷 P3772」游戏
有 个随机真值 , 已知 , 对于 , , . 设事件集合 , 初始时 . 给出 次修改, 每次修改:
- 给定 , 令 .
- 给定 , 令 .
每次修改完成后, 求出 , 保留浮点.
令 , 那么
其中当 内事件全部发生时 , 否则 .
现在, 我们的任务变成了维护出 和 . 容易发现从 的信息推到 的信息是一个线性变换, 我们需要的东西大概有: , , 和 , 其中 , 然后按照规则变换一下:
中间的转移矩阵是 的情况; 当 时, 只需要对应保留矩阵中红色行和蓝色行即可, 其组合意义也比较简单.
最后, 钦定 , 将 输入线性变换, 就能得到最终答案. 线段树维护矩阵, 复杂度 . 常数好像 ... 有点大欸.
/*+Rainybunny+*/
#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
#define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i)
#define double long double
const int MAXN = 2e5;
int n, m;
double p[MAXN + 5], q[MAXN + 5];
struct Matrix {
double mat[4][4];
// Matrix(): mat{} {}
inline double* operator [] (const int k) { return mat[k]; }
inline Matrix operator * (const Matrix& u) const {
Matrix ret; memset(ret.mat, 0, sizeof ret.mat);
rep (i, 0, 3) rep (k, 0, 3) rep (j, 0, 3) {
ret[i][j] += mat[i][k] * u.mat[k][j];
}
return ret;
}
};
#define unknown(i) Matrix{{ \
{ p[i], q[i] }, \
{ 1 - p[i], 1 - q[i] }, \
{ p[i], q[i], p[i], q[i] }, \
{ 0, 0, 1 - p[i], 1 - q[i] } \
}}
#define winR(i) Matrix{{ \
{ p[i], q[i] }, \
{}, \
{ p[i], q[i], p[i], q[i] }, \
{} \
}}
#define winB(i) Matrix{{ \
{}, \
{ 1 - p[i], 1 - q[i] }, \
{}, \
{ 0, 0, 1 - p[i], 1 - q[i] } \
}}
struct SegmentTree {
Matrix uni[MAXN << 2];
inline void pushup(const int u) {
uni[u] = uni[u << 1 | 1] * uni[u << 1];
}
inline void build(const int u, const int l, const int r) {
if (l == r) return void(uni[u] = unknown(l));
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
inline void modify(const int u, const int l, const int r,
const int x, const Matrix k) {
if (l == r) return void(uni[u] = k);
int mid = l + r >> 1;
if (x <= mid) modify(u << 1, l, mid, x, k);
else modify(u << 1 | 1, mid + 1, r, x, k);
pushup(u);
}
} sgt;
int main() {
scanf("%d %d %*s %Lf", &n, &m, &p[1]);
rep (i, 2, n) scanf("%Lf %Lf", &p[i], &q[i]);
sgt.build(1, 1, n);
while (m--) {
char op[10]; int i, c;
scanf("%s", op);
if (op[0] == 'a') {
scanf("%d %d", &i, &c);
sgt.modify(1, 1, n, i, c ? winR(i) : winB(i));
} else {
scanf("%d", &i);
sgt.modify(1, 1, n, i, unknown(i));
}
auto& ans = sgt.uni[1];
printf("%.12Lf\n", (ans[2][0] + ans[3][0]) / (ans[0][0] + ans[1][0]));
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现