HDU 4010 Query on The Trees(动态树LCT)
There are N nodes, each node will have a unique weight Wi. We will have four kinds of operations on it and you should solve them efficiently. Wish you have fun!
For each case, the first line contains only one integer N.(1 ≤ N ≤ 300000) The next N‐1 lines each contains two integers x, y which means there is an edge between them. It also means we will give you one tree initially.
The next line will contains N integers which means the weight Wi of each node. (0 ≤ Wi ≤ 3000)
The next line will contains an integer Q. (1 ≤ Q ≤ 300000) The next Q lines will start with an integer 1, 2, 3 or 4 means the kind of this operation.
1. Given two integer x, y, you should make a new edge between these two node x and y. So after this operation, two trees will be connected to a new one.
2. Given two integer x, y, you should find the tree in the tree set who contain node x, and you should make the node x be the root of this tree, and then you should cut the edge between node y and its parent. So after this operation, a tree will be separate into two parts.
3. Given three integer w, x, y, for the x, y and all nodes between the path from x to y, you should increase their weight by w.
4. Given two integer x, y, you should check the node weights on the path between x and y, and you should output the maximum weight on it.
You should output a blank line after each test case.
题目大意:给出一棵带点权树,有4种操作:连边x到y;删掉以x为根的树种y与其父节点的连边;把x到y路径上所有点的权值+1;询问x到y路径上的最大点权。
推荐论文:《QTREE解法的一些研究》,参考代码:http://www.cnblogs.com/kuangbin/archive/2013/09/04/3300251.html
代码(1156MS):
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std; const int MAXN = ;
const int MAXE = MAXN * ;
const int INF = 0x7fffffff; int ch[MAXN][], pre[MAXN], key[MAXN];
int add[MAXN], rev[MAXN], maxt[MAXN];
bool rt[MAXN]; int head[MAXN];
int to[MAXE], next[MAXE];
int ecnt, n, m, op; inline void init() {
ecnt = ;
for(int i = ; i <= n; ++i) {
head[i] = ch[i][] = ch[i][] = ;
pre[i] = add[i] = rev[i] = ;
rt[i] = true;
}
maxt[] = -INF;
} inline void add_edge(int u, int v) {
to[ecnt] = v; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; next[ecnt] = head[v]; head[v] = ecnt++;
} void dfs(int u) {
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(pre[v]) continue;
pre[v] = u;
dfs(v);
}
} inline void update_max(int r) {
maxt[r] = max(max(maxt[ch[r][]], maxt[ch[r][]]), key[r]);
} inline void update_add(int r, int d) {
if(!r) return ;
key[r] += d;
maxt[r] += d;
add[r] += d;
} inline void update_rev(int r) {
if(!r) return ;
swap(ch[r][], ch[r][]);
rev[r] ^= ;
} inline void pushdown(int r) {
if(add[r]) {
update_add(ch[r][], add[r]);
update_add(ch[r][], add[r]);
add[r] = ;
}
if(rev[r]) {
update_rev(ch[r][]);
update_rev(ch[r][]);
rev[r] = ;
}
} void rotate(int x) {
int y = pre[x], t = ch[y][] == x;
ch[y][t] = ch[x][!t];
pre[ch[y][t]] = y;
pre[x] = pre[y];
pre[y] = x;
ch[x][!t] = y;
if(rt[y]) rt[y] = false, rt[x] = true;
else ch[pre[x]][ch[pre[x]][] == y] = x;
update_max(y);
} void P(int r) {
if(!rt[r]) P(pre[r]);
pushdown(r);
} inline void Splay(int r) {
P(r);
while(!rt[r]) {
int f = pre[r], ff = pre[f];
if(rt[f]) rotate(r);
else if((ch[ff][] == f) == (ch[f][] == r)) rotate(f), rotate(r);
else rotate(r), rotate(r);
}
update_max(r);
} inline int access(int x) {
int y = ;
while(x) {
Splay(x);
rt[ch[x][]] = true, rt[ch[x][] = y] = false;
update_max(x);
x = pre[y = x];
}
return y;
} inline void be_root(int r) {
access(r);
Splay(r);
update_rev(r);
} inline void lca(int &u, int &v) {
access(v), v = ;
while(u) {
Splay(u);
if(!pre[u]) return ;
rt[ch[u][]] = true;
rt[ch[u][] = v] = false;
update_max(u);
u = pre[v = u];
}
} inline int root(int u) {
while(pre[u]) u = pre[u];
return u;
} inline void link(int u, int v) {
if(u == v || root(u) == root(v)) puts("-1");
else {
be_root(u);
pre[u] = v;
}
} inline void cut(int u, int v) {
if(u == v || root(u) != root(v)) puts("-1");
else {
be_root(u);
Splay(v);
pre[ch[v][]] = pre[v];
pre[v] = ;
rt[ch[v][]] = true;
ch[v][] = ;
update_max(v);
}
} inline void modity(int u, int v, int w) {
if(root(u) != root(v)) puts("-1");
else {
lca(u, v);
update_add(ch[u][], w);
update_add(v, w);
key[u] += w;
update_max(u);
}
} inline void query(int u, int v) {
if(root(u) != root(v)) puts("-1");
else {
lca(u, v);
printf("%d\n", max(max(maxt[v], maxt[ch[u][]]), key[u]));
}
} int main() {
while(scanf("%d", &n) != EOF) {
init();
for(int i = ; i < n; ++i) {
int u, v;
scanf("%d%d", &u, &v);
add_edge(u, v);
}
for(int i = ; i <= n; ++i) scanf("%d", &key[i]);
pre[] = -; dfs(); pre[] = ;
scanf("%d", &m);
while(m--) {
scanf("%d", &op);
if(op == ) {
int x, y;
scanf("%d%d", &x, &y);
link(x, y);
}
if(op == ) {
int x, y;
scanf("%d%d", &x, &y);
cut(x, y);
}
if(op == ) {
int x, y, w;
scanf("%d%d%d", &w, &x, &y);
modity(x, y, w);
}
if(op == ) {
int x, y;
scanf("%d%d", &x, &y);
query(x, y);
}
}
puts("");
}
}
HDU 4010 Query on The Trees(动态树LCT)的更多相关文章
- HDU 4010 Query on The Trees (动态树)(Link-Cut-Tree)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4010 题意; 先给你一棵树,有 \(4\) 种操作: 1.如果 \(x\) 和 \(y\) 不在同一 ...
- HDU 4010 Query on The Trees(动态树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4010 题意:一棵树,四种操作: (1)若x和y不在一棵树上,将x和y连边: (2)若x和y在一棵树上, ...
- 动态树(LCT):HDU 4010 Query on The Trees
Query on The Trees Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Othe ...
- HDU 4010.Query on The Trees 解题报告
题意: 给出一颗树,有4种操作: 1.如果x和y不在同一棵树上则在xy连边 2.如果x和y在同一棵树上并且x!=y则把x换为树根并把y和y的父亲分离 3.如果x和y在同一棵树上则x到y的路径上所有的点 ...
- HDU 4010 Query on The Trees(动态树)
题意 给定一棵 \(n\) 个节点的树,每个点有点权.完成 \(m\) 个操作,操作四两种,连接 \((x,y)\) :提 \(x\) 为根,并断 \(y\) 与它的父节点:增加路径 \((x,y)\ ...
- HDU 4010 Query on The Trees
Problem Description We have met so many problems on the tree, so today we will have a query problem ...
- hdu 4010 Query on The Trees LCT
支持:1.添加边 x,y2.删边 x,y3.对于路径x,y上的所有节点的值加上w4.询问路径x,y上的所有节点的最大权值 分析:裸的lct...rev忘了清零死循环了两小时... 1:就是link操作 ...
- hdu 5398 动态树LCT
GCD Tree Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- hdu 5002 (动态树lct)
Tree Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
随机推荐
- App 分辨率相关 - iOS
针对现有 Apple 设备分辨率小归总,方便日常查看; 顺便推荐一款图片生成工具,个人感觉挺方便好用,放置一张高分辨率大图可自动生成一套配图,软件名称(App Icon Gear). 具体设备分辨率如 ...
- c# 常用数据库封装
我不为大家贴代码了,没有意思,有点多,我主要给大家介绍一下,源码会上传CSDN和GIT:我定义了一个ADO.NET操作接口,所有按照接口封装 1.sqlite数据库(需要SQLite.Interop. ...
- poj_2249_Binomial Showdown
In how many ways can you choose k elements out of n elements, not taking order into account? Write a ...
- hdu_2588_GCD
The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written (a,b),is the ...
- IDEA项目启动报Unable to open debugger port (127.0.0.1:51554): java.net.SocketException "socket closed"
启动报错: Unable to open debugger port (127.0.0.1:51554): java.net.SocketException "socket closed&q ...
- Chrome浏览器调试移动端网页 chrome://inspect/#devices
我使用的是魅族(魅蓝NOTE6 ),电脑是win 7系统,以下几步就可以轻松使用浏览器内置的功能调试移动端网页了: 注意:谷歌浏览器需要先FQ,不然调试页面会空白或者报404错误,(不会FQ的可以联系 ...
- python mac下安装虚拟环境
Mac 下 Flask 框架 workon命令找不到 ---- 最终解决方案(详解具体实现操作过程中遇到的坑) Mac 下 Flask 的 全网最详细搭建 1.安装virtualenv和virtual ...
- liunx下搭建python开发环境
=============================================================================注意: 在linux下安装新的版本的pytho ...
- java程序——从命令行接收多个数字,求和之后输出结果
命令行参数都是字符串,必须先将其转化为数字,才能相加.以下是流程图,源代码和输出结果. 流程图: 源代码: import java.util.Scanner; public class Test { ...
- 对C语言连等式的学习
例子如下 [pgsql@localhost soft]$ cat test1.c #include <stdlib.h> #include <stdio.h> int main ...