CF176E Archaeology

有一棵 \(n\) 个点的带权树,每个点都是黑色或白色,最初所有点都是白色的。有 \(m\) 个询问:

  • 把点 \(x\) 从白色变成黑色
  • 把点 \(x\) 从黑色变成白色
  • 查询黑点的导出子树的边权和

\(1 \leq n,\ q \leq 10^5,\ 1\leq x\leq n\) 。

LCA


双倍经验 bzoj3991 [SDOI2015]寻宝游戏

结论:

  • 按照时间戳把所有黑点升序排序,累加相邻及首尾两点之间的路径长度,最后得到的结果恰好是所求答案的两倍

于是可以用一个数据结构按照时间戳递增的顺序维护黑点序列,算插/删点的贡献用 \(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的更多相关文章

  1. CF176E Archaeology(set用法提示)

    题目大意: 给一棵树,每次激活或熄灭一个点,每次问这些点都联通起来所需的最小总边权 分析: 若根据dfs序给所有点排序,为$v1,v2,v3....vk$,那么答案就是$(dis(v1,v2)+dis ...

  2. Codeforces 1178E. Archaeology

    传送门 首先一定有解,考虑归纳法证明 首先 $n<=3$ 时显然 考虑 $n=4$ 时,那么因为 $s[1]!=s[2],s[3]!=s[4]$ ,并且 $s[i] \in {a,b,c}$ 由 ...

  3. CF 1178E Archaeology 题解

    题面 这道题竟然是E?还是洛谷中的黑题? wow~!! 于是就做了一下: 然后一下就A了:(这并不代表想的容易,而是写的容易) 这道题就是骗人的!! 什么manacher,什么回文自动机,去靠一边站着 ...

  4. Codeforces 1178E Archaeology (鸽巢原理)

    题意: 给你1e6的字符串,保证只含'a''b''c'三种字符,且相邻两个字符一定不一样 求一个大于等于n/2的回文子序列 思路: 朴素的最长回文子序列是n方的区间dp,这题显然不行,要充分利用题中所 ...

  5. 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 ...

  6. What Can I Do With This Major?

    What Can I Do With This Major? Majors Don’t see your major? Accounting Advertising Africana Studies ...

  7. 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 & ...

  8. 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 ...

  9. css页面组件

    页面组件 1 元素的尺寸/边框/背景 1.1 css尺寸相关属性 height 高度 min-height 最小高度 max-height 最大高度 width 宽度 min-width 最小宽度 m ...

随机推荐

  1. 向后台提交数据:利用cookie加session提交更多数据,

    个人逻辑,可能考虑不全面,各位看到后留言,我修改啊 实现效果:浏览器第一次访问提交用户名,后台验证通过,生成随机字符串,和用户名组成字典,保存到服务器,把随机字符串设置成cookie发给浏览器,同一个 ...

  2. iOS----------开发中常用的宏有那些

    OC对象判断是否为空? 字符串是否为空 #define kStringIsEmpty(str) ([str isKindOfClass:[NSNull class]] || str == nil || ...

  3. svn checkout 实用小技巧

    svn checkout 实用小技巧 by:授客 QQ:1033553122   问题描述: 用svn小乌龟软件,进行update,commit之前,先要把svn工作目录checkout到本地,那么问 ...

  4. 小程序问题集:保存失败:Error: ENOENT: no such file or directory, open

    问题如图: 当编译的时候 会提示找不到这个文件(index),但是确信项目目录里已经删除了该页面路径,并且app.json的pages列表中也没有该页面:   这时候需要看一下当前已经打开的文件中是否 ...

  5. Android 7.0 新特性

    Android7.0提供新功能以提升性能.生产效率和安全性. 关于Android N的性能改进,Android N建立了先进的图形处理Vulkan系统,能少的减少对CPU的占用.与此同时,Androi ...

  6. 列表转换为字典(setdefault())

    li=[11,22,33,44,66,77,88] dict={} li_less=[] li_large=[] for i in li: if i == 66:continue if i < ...

  7. (网页)HTML5 Canvas ( 事件交互, 点击事件为例 ) isPointInPath(转)

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. Makefile中通过sed命令生成文件系统的selinux的配置文件vendor_filesystem_config.txt

    今天在编译android-O(8.0)的时候,我自己新增加了一个ext4格式的分区,在编译这个分区的时候,需要对应的生成文件系统的配置文件xxxx_filesystem_config.txt,发现了生 ...

  9. 口碑订单,ERP本地加/退菜无法回流至手机端的解决办法-订单金额不统一erp本地加菜H5没有

    关于 口碑订单,ERP本地加/退菜无法回流至手机端的解决办法-订单金额不统一erp本地加菜H5没有 1. 2. 3. PS:是正餐后付的务必要选择口碑后付 完成以上设置即可

  10. EOS智能合约开发(四):智能合约部署及调试(附编程示例)

    EOS智能合约开发(一):EOS环境搭建和创建节点 EOS智能合约开发(二):EOS创建和管理钱包 EOS智能合约开发(三):EOS创建和管理账号 部署智能合约的示例代码如下: $ cleos set ...