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 ...
随机推荐
- IE CSS Hack【记录】
1.条件hack 2.属性hack 3.选择器hack CSS Hack一般都是利用各浏览器的支持CSS的能力和BUG来进行的 本文只列举了一些常用的CSS Hack,且不考虑IE6以下的版本 尽可能 ...
- Android中Ijkplayer最简单的使用
先添加依赖: compile 'com.dou361.ijkplayer:jjdxm-ijkplayer:1.0.5' MainActivity里面: public class MainActivit ...
- Wu反走样算法绘制圆(C++/MFC实现)
Wu反走样圆 原理:参考Bresenham算法,在主位移过程中计算出离理想圆最近的两个点,赋予不同的亮度值,绘制像素点即可! MFC 中CXXXView类中添加函数: //Wu算法画反走样圆 void ...
- JAVA项目从运维部署到项目开发(二.ZooKeeper)
一.zookeeper的相关介绍 点击查看 二.下载.安装与配置 1.ZooKeeper官网下载地址(点击跳转),当前稳定版本为V3.4.12.Liniux下可以在指定目录,使用wget命令下载. h ...
- vertical-align属性探究
在前端开发中我们经常需要将元素垂直居中对齐,我们很自然的想到使用vertical-align属性,但是使用后却发现有时候能起作用,有时候却又不起作用.究其原因还是因为我们没有将vertical-ali ...
- Jenkins 安装 on centos7
本文演示如何在CentOS7上安装jenkins. 1 准备工作 1.1 选择安装节点 因为在DevOps实践环境搭建规划中,Jenkins的任务需要执行docker swarm的相关命令,简单起见, ...
- MySQL 5.7忘记root密码如何修改?
一直以来,MySQL的应用和学习环境都是MySQL 5.6和之前的版本,也没有去关注新版本MySQL 5.7的变化和新特性.今天帮人处理忘记root密码的时时候,发现以前的方法不奏效了.具体情况如下所 ...
- js强制不使用“兼容性视图”
在IE8浏览器以后版本,都有一个“兼容性视图”,让不少新技术无法使用.那么如何禁止浏览器自动选择“兼容性视图”,强制IE以最高级别的可用模式显示内容呢?下面就介绍一段HTML代码. X-UA-Comp ...
- python发展史
一:Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum)(龟叔).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹 打发时间,决心开发一个新的脚本解释程序, ...
- Linux下完全删除用户
实验环境:Centos7虚拟机 首先创建一个普通用户gubeiqing. [root@localhost ~]# useradd gubeiqing [root@localhost ~]# passw ...