P3250 网络 题解

news/2024/10/7 9:27:20/文章来源:https://www.cnblogs.com/laijinyi/p/18449769

Solution

单次二分:问“重要度 \(\ge x\) 的所有操作,且 \(t\) 时间点还存在的所有操作中,是否有不经过这个点的”

整体二分:保持操作、询问按时间有序,即预先按时间排序,下传时保持有序;

对于一次 Solve,对于所有重要度 \(\ge mid+1\) 的操作(加入、删除),考虑与询问按时间混合排序,然后依次回答。

这里有比树剖更好的处理方法:树上差分,一次加入路径 \((u,v)\) 就给 \(u,v\) 加一,\(lca,fa(lca)\) 减一;一次询问 \(u\) 就查 \(u\) 子树和是否等于操作数,树状数组可以实现。

用不用 \(O(1)\) LCA 都是 \(O(n\log^2 n)\) 的.

Code 1

\(\text{vector}\) 版整体二分,未卡常

#include <bits/stdc++.h>
using namespace std;
#define rep(i, j, k) for (int i = (j); i <= (k); ++i)
#define reo(i, j, k) for (int i = (j); i >= (k); --i)
typedef long long ll;
const int N = 1e5 + 10, M = 2e5 + 10;
int n, m, tot, ans[N];
vector<int> G[N];
struct Item {int op, u, v, w, tim, id;
};int tim, dfn[N], dep[N], sz[N], son[N], Top[N], Fa[N];
void DFS1(int u, int fa) {sz[u] = 1, Fa[u] = fa, dep[u] = dep[fa] + 1;for (int v : G[u])if (v != fa) {DFS1(v, u), sz[u] += sz[v];if (sz[v] > sz[son[u]]) son[u] = v;}
}
void DFS2(int u, int tp) {dfn[u] = ++tim, Top[u] = tp;if (son[u]) DFS2(son[u], tp);for (int v : G[u])if (v != Fa[u] && v != son[u])DFS2(v, v);
}
int LCA(int u, int v) {while (Top[u] != Top[v]) {if (dep[Top[u]] < dep[Top[v]]) swap(u, v);u = Fa[Top[u]];}return dep[u] < dep[v] ? u : v;
}struct BIT {ll sum[N];BIT() {memset(sum, 0, sizeof(sum));}void Upd(int x, ll v) {for (; x <= n; x += x & -x) sum[x] += v;}ll Qry(int x) {ll res = 0;for (; x; x -= x & -x) res += sum[x];return res;}ll Qry(int x, int y) {return Qry(y) - Qry(x - 1);}
} bit;void Solve(int l, int r, vector<Item> &Op) {int cntQ = 0;for (auto it : Op) cntQ += it.op == 2;if (!cntQ) return;if (l == r) {for (auto it : Op) {if (it.op == 2) ans[it.id] = (l == 1) ? -1 : (l - 1);}return;}int mid = (l + r) >> 1;vector<Item> OpL, OpR;int cnt = 0;for (auto it : Op) {if (it.op == 0) {if (it.w >= mid) {int u = it.u, v = it.v, lca = LCA(u, v), fa = Fa[lca];bit.Upd(dfn[u], 1), bit.Upd(dfn[v], 1), bit.Upd(dfn[lca], -1);if (fa) bit.Upd(dfn[fa], -1);++cnt;}if (it.w > mid) OpR.push_back(it);else OpL.push_back(it);}if (it.op == 1) {if (it.w >= mid) {int u = it.u, v = it.v, lca = LCA(u, v), fa = Fa[lca];bit.Upd(dfn[u], -1), bit.Upd(dfn[v], -1), bit.Upd(dfn[lca], 1);if (fa) bit.Upd(dfn[fa], 1);--cnt;}if (it.w > mid) OpR.push_back(it);else OpL.push_back(it);}if (it.op == 2) {int res = bit.Qry(dfn[it.u], dfn[it.u] + sz[it.u] - 1);if (res == cnt) {OpL.push_back(it);} else {OpR.push_back(it);}}}for (auto it : Op) {if (it.op == 0 && it.w >= mid) {int u = it.u, v = it.v, lca = LCA(u, v), fa = Fa[lca];bit.Upd(dfn[u], -1), bit.Upd(dfn[v], -1), bit.Upd(dfn[lca], 1);if (fa) bit.Upd(dfn[fa], 1);}if (it.op == 1 && it.w >= mid) {int u = it.u, v = it.v, lca = LCA(u, v), fa = Fa[lca];bit.Upd(dfn[u], 1), bit.Upd(dfn[v], 1), bit.Upd(dfn[lca], -1);if (fa) bit.Upd(dfn[fa], -1);}}Solve(l, mid, OpL), Solve(mid + 1, r, OpR);
}int main() {ios::sync_with_stdio(false), cin.tie(nullptr);cin >> n >> m;rep(i, 1, n - 1) {int u, v;cin >> u >> v, G[u].push_back(v), G[v].push_back(u);}int mx = 0;vector<Item> Op(m);rep(i, 0, m - 1) {int x;cin >> Op[i].op;if (Op[i].op == 0) cin >> Op[i].u >> Op[i].v >> Op[i].w, mx = max(mx, Op[i].w);if (Op[i].op == 1) cin >> x, --x, Op[i].u = Op[x].u, Op[i].v = Op[x].v, Op[i].w = Op[x].w;if (Op[i].op == 2) cin >> Op[i].u, Op[i].id = ++tot;}DFS1(1, 0), DFS2(1, 1);Solve(1, mx + 1, Op);rep(i, 1, tot) cout << ans[i] << '\n';return 0;
}

Code 2

普通整体二分

#include <bits/stdc++.h>
using namespace std;
#define rep(i, j, k) for (int i = (j); i <= (k); ++i)
#define reo(i, j, k) for (int i = (j); i >= (k); --i)
typedef long long ll;
const int N = 1e5 + 10, M = 2e5 + 10;
int n, m, tot, ans[M];
vector<int> G[N];
struct Item {int op, u, v, w, tim, id;
} Op[M];
int id[M], _id[M], vis[M];int tim, dfn[N], dep[N], sz[N], son[N], Top[N], Fa[N];
void DFS1(int u, int fa) {sz[u] = 1, Fa[u] = fa, dep[u] = dep[fa] + 1;for (int v : G[u])if (v != fa) {DFS1(v, u), sz[u] += sz[v];if (sz[v] > sz[son[u]]) son[u] = v;}
}
void DFS2(int u, int tp) {dfn[u] = ++tim, Top[u] = tp;if (son[u]) DFS2(son[u], tp);for (int v : G[u])if (v != Fa[u] && v != son[u])DFS2(v, v);
}
int LCA(int u, int v) {while (Top[u] != Top[v]) {if (dep[Top[u]] < dep[Top[v]]) swap(u, v);u = Fa[Top[u]];}return dep[u] < dep[v] ? u : v;
}struct BIT {ll sum[N];BIT() {memset(sum, 0, sizeof(sum));}void Upd(int x, ll v) {for (; x <= n; x += x & -x) sum[x] += v;}ll Qry(int x) {ll res = 0;for (; x; x -= x & -x) res += sum[x];return res;}ll Qry(int x, int y) {return Qry(y) - Qry(x - 1);}
} bit;void Solve(int l, int r, int ql, int qr) {int cntQ = 0;rep(i, ql, qr) cntQ += Op[id[i]].op == 2;if (!cntQ) return;if (l == r) {rep(i, ql, qr) {auto it = Op[id[i]];if (it.op == 2) ans[it.id] = (l == 1) ? -1 : (l - 1);}return;}int mid = (l + r) >> 1, cnt = 0, L = ql - 1, R;rep(i, ql, qr) {auto it = Op[id[i]];if (it.op == 0) {if (it.w >= mid) {int u = it.u, v = it.v, lca = LCA(u, v), fa = Fa[lca];bit.Upd(dfn[u], 1), bit.Upd(dfn[v], 1), bit.Upd(dfn[lca], -1);if (fa) bit.Upd(dfn[fa], -1);++cnt;}if (it.w > mid) vis[i] = 1;else _id[++L] = id[i], vis[i] = 0;}if (it.op == 1) {if (it.w >= mid) {int u = it.u, v = it.v, lca = LCA(u, v), fa = Fa[lca];bit.Upd(dfn[u], -1), bit.Upd(dfn[v], -1), bit.Upd(dfn[lca], 1);if (fa) bit.Upd(dfn[fa], 1);--cnt;}if (it.w > mid) vis[i] = 1;else _id[++L] = id[i], vis[i] = 0;}if (it.op == 2) {int res = bit.Qry(dfn[it.u], dfn[it.u] + sz[it.u] - 1);if (res == cnt) {_id[++L] = id[i], vis[i] = 0;} else {vis[i] = 1;}}}R = L;rep(i, ql, qr) if (vis[i]) _id[++R] = id[i];rep(i, ql, qr) {auto it = Op[id[i]];if (it.op == 0 && it.w >= mid) {int u = it.u, v = it.v, lca = LCA(u, v), fa = Fa[lca];bit.Upd(dfn[u], -1), bit.Upd(dfn[v], -1), bit.Upd(dfn[lca], 1);if (fa) bit.Upd(dfn[fa], 1);}if (it.op == 1 && it.w >= mid) {int u = it.u, v = it.v, lca = LCA(u, v), fa = Fa[lca];bit.Upd(dfn[u], 1), bit.Upd(dfn[v], 1), bit.Upd(dfn[lca], -1);if (fa) bit.Upd(dfn[fa], -1);}}rep(i, ql, qr) id[i] = _id[i];Solve(l, mid, ql, L), Solve(mid + 1, r, L + 1, qr);
}int main() {ios::sync_with_stdio(false), cin.tie(nullptr);cin >> n >> m;rep(i, 1, n - 1) {int u, v;cin >> u >> v, G[u].push_back(v), G[v].push_back(u);}int mx = 0;rep(i, 1, m) {int x;cin >> Op[i].op;if (Op[i].op == 0) cin >> Op[i].u >> Op[i].v >> Op[i].w, mx = max(mx, Op[i].w);if (Op[i].op == 1) cin >> x, Op[i].u = Op[x].u, Op[i].v = Op[x].v, Op[i].w = Op[x].w;if (Op[i].op == 2) cin >> Op[i].u, Op[i].id = ++tot;id[i] = i;}DFS1(1, 0), DFS2(1, 1), Solve(1, mx + 1, 1, m);rep(i, 1, tot) cout << ans[i] << '\n';return 0;
}

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

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

相关文章

江苏省第二届数据安全技术应用职业技能竞赛初赛WP

一、数据安全解题赛1、ds_0602解题思路题目让我们获取加密文件中的原始数据,解密后提交第六行第二列数据,下载附件,发现里面有两个文件,其中一个是“.enc”结尾,那这里我们得先简单了解一下“.enc”结尾的是什么类型的文件。简单来说“.enc”结尾的文件通常是经过加密的文…

java之使用CompletableFuture入门2

Java 17 -序章 本文介绍用过的 allOf、anyOf 函数的用法。allOf 函数原型两点: 1、没有返回值。 2、参数 cfs 中 任何一个 都不能是 null。anyOf 函数原型两点: 1、有返回值,为 Object。 2、参数 cfs 中 任何一个 都不能是 null。allOf 测试意图: 多个任务正常执行。ben发布…

VMware Aria Operations for Logs 8.18 发布,新增功能概览

VMware Aria Operations for Logs 8.18 发布,新增功能概览VMware Aria Operations for Logs 8.18 - 集中式日志管理 请访问原文链接:https://sysin.org/blog/vmware-aria-operations-for-logs/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org集中式日志管理 V…

VMware Aria Operations for Networks 6.13 发布,新增功能概览

VMware Aria Operations for Networks 6.13 发布,新增功能概览VMware Aria Operations for Networks 6.13 - 网络和应用监控工具 请访问原文链接:https://sysin.org/blog/vmware-aria-operations-for-networks/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org…

读数据工程之道:设计和构建健壮的数据系统01数据工程概述

数据工程概述1. 数据工程 1.1. 自从公司开始使用数据做事,数据工程就以某种形式存在了1.1.1. 预测性分析、描述性分析和报告1.2. 数据工程师获取数据、存储数据,并准备数据供数据科学家、分析师和其他人使用 1.3. 数据工程是系统和流程的开发、实施和维护,这些系统和流程接收…

安装socks5的一次尝试

1. 下载并自动配置socks5sudo wget https://ap-guangzhou-1257892306.cos.ap-guangzhou.myqcloud.com/asi/httpsocks5.sh && sh httpsocks5.sh 执行下载脚本 wget —no-check-certificate https://raw.github.com/Lozy/danted/master/install.sh -O install.sh执行安装…

形函数的构造7

形函数构造 构造单元1的一般近似函数 \(\overline{V(x)}^{(1)}\),由于该单元只有两个节点\(x_1\)和\(x_2\),我们选择包含两个参数\(\alpha_1\)和\(\alpha_2\)的近似方程 \[\overline{V(x)}^{(1)}=\alpha_1+\alpha_2\times x \]令试函数与\(V(x)\)在节点\(x_1\)和\(x_2\)处相等…

等参单元4

在自然坐标系中 , \(\xi_2=1\)和 \(\xi_2=1\),在物理坐标系中为 \(x_1\) 和\(x_2\),相应的节点位移为\(u_1\) 和\(u_2\) 。 在自然坐标系 下,单元形函数为 \[N_{1}(\xi)=\frac{1}{2}(1-\xi)\\N_{2}(\xi)=\frac{1}{2}(1+\xi) \] 利用形函数,在自然坐标系下单元内的任一点 \(…

二维或三维的分布积分方法(格林公式)7

二维或三维的分布积分(格林公式) 分布积分对下式积分 \[\int\int_{\Omega}\Phi\frac{\partial\Psi}{\partial x}\mathrm{d}x\mathrm{d}y \] 首先对变量\(x\)分布积分 \[\int\limits_{X_L}^{X_R}U\mathrm{d}V=(UV_{X=X_R}-UV_{X=X_L})-\int\limits_{X_L}^{X_R}V\mathrm{d}U \]…

流体力学8-3

第一章 1.1 流体的概念 任何固体材料都有一个强度极限,即使合外力和力矩都为零,它的内部也可能会存在着拉力、压力或者剪切力。当这些内应力超过了材料的强度极限时,固体就会被破坏,从而产生运动。微观上体现为断裂处的分子(或原子)之间的化学键被破坏,失去了相互的作用…

应力分析7

目录3.1 几个基本概念3.3 任意斜截面上的应力3.4 主应力及应力(张量)不变量3.5 最大、最小正应力和最大剪应力 3.1 几个基本概念 • 外力 外力指的是我们熟知的机械力、电磁力等,物体因外力作用而变形。作用于物体的外力可分为体积力和表面 力,它们分别简称为体力和面力。…