CF176E Archaeology
有一棵 \(n\) 个点的带权树,每个点都是黑色或白色,最初所有点都是白色的。有 \(m\) 个询问:
- 把点 \(x\) 从白色变成黑色
- 把点 \(x\) 从黑色变成白色
- 查询黑点的导出子树的边权和
\(1 \leq n,\ q \leq 10^5,\ 1\leq x\leq n\) 。
LCA
结论:
- 按照时间戳把所有黑点升序排序,累加相邻及首尾两点之间的路径长度,最后得到的结果恰好是所求答案的两倍
于是可以用一个数据结构按照时间戳递增的顺序维护黑点序列,算插/删点的贡献用 \(lca\) 维护
这个数据结构需要支持插入、求前驱后继,直接用 \(set\) 就吼辣
时间复杂度 \(O(n\log n)\)
代码
#include <bits/stdc++.h>
using namespace std;
#define iter set <int> :: iterator
typedef long long ll;
const int maxn = 1e5 + 10;
ll ans, dis[maxn];
int n, m, tid[maxn], rk[maxn], h[maxn];
int sz[maxn], fa[maxn], dep[maxn], son[maxn], top[maxn];
set <int> seq;
struct edges {
int nxt, to, w;
} e[maxn << 1];
void addline(int u, int v, int w) {
static int cnt = 1;
e[++cnt] = edges{h[u], v, w}, h[u] = cnt;
}
int dfs1(int u, int f) {
fa[u] = f, dep[u] = dep[f] + 1;
for (int i = h[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v != f) {
dis[v] = dis[u] + e[i].w;
sz[u] += dfs1(v, u);
if (sz[son[u]] < sz[v]) {
son[u] = v;
}
}
}
return ++sz[u];
}
void dfs2(int u, int tp) {
static int now;
top[u] = tp;
tid[u] = ++now, rk[now] = u;
if (son[u]) dfs2(son[u], tp);
for (int i = h[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v != fa[u] && v != son[u]) {
dfs2(v, v);
}
}
}
ll lca(int u, int v) {
ll res = dis[u] + dis[v];
while (top[u] != top[v]) {
if (dep[top[u]] > dep[top[v]]) {
u = fa[top[u]];
} else {
v = fa[top[v]];
}
}
int _lca = dep[u] < dep[v] ? u : v;
return res - 2 * dis[_lca];
}
ll query(iter it) {
iter pre = it, nxt = it;
pre = it == seq.begin() ? seq.end() : it, pre--;
if (++nxt == seq.end()) nxt = seq.begin();
int l = rk[*pre], r = rk[*nxt], u = rk[*it];
return lca(l, u) + lca(u, r) - lca(l, r);
}
int main() {
scanf("%d", &n);
for (int i = 1, u, v, w; i < n; i++) {
scanf("%d %d %d", &u, &v, &w);
addline(u, v, w), addline(v, u, w);
}
dfs1(1, 0), dfs2(1, 1);
scanf("%d", &m);
iter it, tmp;
char c; int x;
while (m--) {
scanf("%s", &c);
if (c == '?') {
printf("%I64d\n", ans >> 1);
continue;
}
scanf("%d", &x);
if (c == '+') {
it = seq.insert(tid[x]).first;
if (seq.size() > 2) {
ans += query(it);
} else if (seq.size() == 2) {
tmp = it == seq.begin() ? ++it : seq.begin();
ans = lca(rk[*tmp], x) << 1;
}
} else {
it = seq.find(tid[x]);
if (seq.size() > 2) {
ans -= query(it);
} else if (seq.size() == 2) {
ans = 0;
}
seq.erase(tid[x]);
}
}
return 0;
}
CF176E Archaeology的更多相关文章
- CF176E Archaeology(set用法提示)
题目大意: 给一棵树,每次激活或熄灭一个点,每次问这些点都联通起来所需的最小总边权 分析: 若根据dfs序给所有点排序,为$v1,v2,v3....vk$,那么答案就是$(dis(v1,v2)+dis ...
- Codeforces 1178E. Archaeology
传送门 首先一定有解,考虑归纳法证明 首先 $n<=3$ 时显然 考虑 $n=4$ 时,那么因为 $s[1]!=s[2],s[3]!=s[4]$ ,并且 $s[i] \in {a,b,c}$ 由 ...
- CF 1178E Archaeology 题解
题面 这道题竟然是E?还是洛谷中的黑题? wow~!! 于是就做了一下: 然后一下就A了:(这并不代表想的容易,而是写的容易) 这道题就是骗人的!! 什么manacher,什么回文自动机,去靠一边站着 ...
- Codeforces 1178E Archaeology (鸽巢原理)
题意: 给你1e6的字符串,保证只含'a''b''c'三种字符,且相邻两个字符一定不一样 求一个大于等于n/2的回文子序列 思路: 朴素的最长回文子序列是n方的区间dp,这题显然不行,要充分利用题中所 ...
- UVALive 7267 Mysterious Antiques in Sackler Museum (判断长方形)
Sackler Museum of Art and Archaeology at Peking University is located on a beautiful site near the W ...
- What Can I Do With This Major?
What Can I Do With This Major? Majors Don’t see your major? Accounting Advertising Africana Studies ...
- 49、word2vec - tensorflow
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)] on win32Type & ...
- How To Make A Swipeable Table View Cell With Actions – Without Going Nuts With Scroll Views
How To Make A Swipeable Table View Cell With Actions – Without Going Nuts With Scroll Views Ellen S ...
- css页面组件
页面组件 1 元素的尺寸/边框/背景 1.1 css尺寸相关属性 height 高度 min-height 最小高度 max-height 最大高度 width 宽度 min-width 最小宽度 m ...
随机推荐
- 前端学习 之 Bootstrap(二)
一.代码 内联代码:用<code>包裹,但是需要用<和>表示尖括号. 键盘输入:用<kbd>包裹表示键盘输入的内容. 多行代码:用<pre>包裹多行代码 ...
- JavaScript之Number、String、Array常用属性与方法手册
Number isFinite函数 Number.isFinite() 方法用来检测传入的参数是否是一个有穷数(finite number). 语法: Number.isFinite(value) 例 ...
- mybatis 自动生成文件配置
maven 依赖配置: <!-- sql server --><dependency> <groupId>com.microsoft.sqlserver</g ...
- 解决ie6中png图片格式不兼容问题
在IE6中对图片格式png24支持度不高,如果使用的图片格式是png24,则会导致透明效果无法正常显示 解决方法: 1.可以使用png8来代替png24,即可解决问题,但是使用png8代替png24以 ...
- Python Python实现批量安装android apk包
基于Python实现批量安装android apk包 by:授客 QQ:1033553122 1.相关软件包及文件下载 下载地址:adb软件包及批量安装apk包的py文件.zip 2.测试环境 Win ...
- 布局优化之ViewStub源码分析
源码分析 @RemoteView public final class ViewStub extends View { private int mInflatedId; private int mLa ...
- matlab练习程序(点集配准的SVD法)
上一篇博客中我们使用了四元数法计算ICP. 本篇我们使用SVD计算ICP. 下面是<视觉slam十四讲>中的计算方法: 计算步骤如下: 我们看到,只要求出了两组点之间的旋转,平移是非常容易 ...
- LeetCode题解之Binary Tree Right Side View
1.题目描述 2.问题分析 使用层序遍历 3.代码 vector<int> v; vector<int> rightSideView(TreeNode* root) { if ...
- 没有服务商如何购买ERP的序列号?
一.试用期(未过期) 站点版购买: 门店版购买: 二.试用期(使用时间<=15天) 三.试用期(已过期) 登录时会弹出以下弹窗 剩下的购买步骤与未过期时购买步骤一致 四.续费 剩下步骤与未过期时 ...
- [20180904]工作中一个错误.txt
[20180904]工作中一个错误.txt --//昨天看我提交一份修改建议,发现自己写的sql语句存在错误.--//链接:http://blog.itpub.net/267265/viewspace ...