题意:

  给出一颗树,有4种操作:

1、如果x和y不在同一棵树上则在xy连边

2、如果x和y在同一棵树上并且x!=y则把x换为树根并把y和y的父亲分离

3、如果x和y在同一棵树上则x到y的路径上所有的点权值+w

4、如果x和y在同一棵树上则输出x到y路径上的最大值

动态树入门题:

#include <iostream>
#include <cstdio>
using namespace std; const int MAXN = 333333; struct node {
int val, max, inc;
bool rev;
node *par, *Ch[2];
} dt[MAXN], *NIL = dt; struct LinkcutTree {
inline void _inc (node * x, int inc) {
if (x == NIL) return;
x->inc += inc, x->val += inc, x->max += inc;
}
inline void clear (node *const x) {
if (x == NIL) return ;
if (x->inc) {
_inc (x->Ch[0], x->inc);
_inc (x->Ch[1], x->inc);
x->inc = 0;
}
if (x->rev) {
swap (x->Ch[0], x->Ch[1]);
x->Ch[0]->rev ^= 1;
x->Ch[1]->rev ^= 1;
x->rev = 0;
}
}
inline void update (node * x) {
clear (x);
clear (x->Ch[0]), clear (x->Ch[1]);
x->max = max (x->val, max (x->Ch[0]->max, x->Ch[1]->max) );
}
void Rotate (node *x) {
node *p = x->par, *g = p->par;
clear (p),clear (x);
int c = p->Ch[0] == x; //0左旋,1右旋
p->Ch[c ^ 1] = x->Ch[c];
if (x->Ch[c] != NIL) x->Ch[c]->par = p;
x->par = g;
if (g->Ch[0] == p) g->Ch[0] = x; else
if (g->Ch[1] == p) g->Ch[1] = x;
x->Ch[c] = p;
p->par = x;
update (p);
}
void Splay (node *x) {
if(x==NIL) return ;
while (x->par != NIL && (x->par->Ch[0] == x || x->par->Ch[1] == x) ) {
if (x->par != NIL)
Rotate (x);
else {
node *p = x->par, *g = p->par;
if ( (g->Ch[1] == p) == (p->Ch[1] == x) )
Rotate (p), Rotate (x);
else
Rotate (x), Rotate (x);
}
}
update (x);
}
node *Access (node *u) {
node *v = NIL;
for (; u != NIL; u = u->par) {
Splay (u);
u->Ch[1] = v;
update (v = u);
}
return v;
}
node *getroot (node *x) {
for (x = Access (x); clear (x), x->Ch[0] != NIL; x = x->Ch[0]);
return x;
}
inline void evert (node *x) {
Access (x)->rev ^= 1;
Splay (x);
}
inline void link (node *x, node *y) {
evert (x);
x->par = y;
Access (x);
}
inline void cut (node *x, node *y) {
evert (x);
Access (y);
Splay (y);
y->Ch[0]->par = NIL;
y->Ch[0] = NIL;
update (y);
}
inline int query (node *x, node *y) {
evert (x);
Access (y), Splay (y);
return y->max;
}
inline void modify (node *x, node *y, int w) {
evert (x);
Access (y), Splay (y);
_inc (y, w);
}
} LCT;
int n, m;
int main() {
while (scanf ("%d", &n) != EOF) {
for (int i = 0; i <= n; i++) {
dt[i].val = dt[i].max = dt[i].inc = 0;
dt[i].par = dt[i].Ch[0] = dt[i].Ch[1] = NIL;
dt[i].rev = 0;
}
for (int i = 1, x, y; i < n; ++i) {
scanf ("%d %d", &x, &y);
LCT.link (dt + x, dt + y);
}
for (int i = 1, x; i <= n; ++i) {
scanf ("%d", &x);
node *tem = dt + i;
LCT.Splay (tem);
tem->val = tem->max = x;
LCT.update (tem);
}
scanf ("%d", &m);
for (int i = 0, op, x, y, z; i < m; ++i) {
scanf ("%d%d%d", &op, &x, &y);
switch (op) {
case 1:
if (LCT.getroot (dt + x) == LCT.getroot (dt + y) ) printf ("-1\n");
else LCT.link (dt + x, dt + y); break;
case 2:
if (x == y || LCT.getroot (dt + x) != LCT.getroot (dt + y) ) printf ("-1\n");
else LCT.cut (dt + x, dt + y); break;
case 3:
scanf ("%d", &z);
if (LCT.getroot (dt + y) != LCT.getroot (dt + z) ) printf ("-1\n");
else LCT.modify (dt + y, dt + z, x); break;
case 4:
if (LCT.getroot (dt + x) != LCT.getroot (dt + y) ) printf ("-1\n");
else printf ("%d\n", LCT.query (dt + x, dt + y) ); break;
}
}
putchar (10);
}
}

HDU 4010.Query on The Trees 解题报告的更多相关文章

  1. 动态树(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 ...

  2. HDU 4010 Query on The Trees (动态树)(Link-Cut-Tree)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4010 题意; 先给你一棵树,有 \(4\) 种操作: 1.如果 \(x\) 和 \(y\) 不在同一 ...

  3. HDU 4010 Query on The Trees(动态树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4010 题意:一棵树,四种操作: (1)若x和y不在一棵树上,将x和y连边: (2)若x和y在一棵树上, ...

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

  5. HDU 4010 Query on The Trees(动态树LCT)

    Problem Description We have met so many problems on the tree, so today we will have a query problem ...

  6. HDU 4010 Query on The Trees(动态树)

    题意 给定一棵 \(n\) 个节点的树,每个点有点权.完成 \(m\) 个操作,操作四两种,连接 \((x,y)\) :提 \(x\) 为根,并断 \(y\) 与它的父节点:增加路径 \((x,y)\ ...

  7. hdu 4010 Query on The Trees LCT

    支持:1.添加边 x,y2.删边 x,y3.对于路径x,y上的所有节点的值加上w4.询问路径x,y上的所有节点的最大权值 分析:裸的lct...rev忘了清零死循环了两小时... 1:就是link操作 ...

  8. HDOJ 4010 Query on The Trees LCT

    LCT: 分割.合并子树,路径上全部点的点权添加一个值,查询路径上点权的最大值 Query on The Trees Time Limit: 10000/5000 MS (Java/Others)   ...

  9. 【LeetCode】951. Flip Equivalent Binary Trees 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcod ...

随机推荐

  1. eclipse常见错误

    1.The superclass “javax.servlet.http.httpservlet” is not found in the build path 原因:未添加server librar ...

  2. 最大流算法---Edmond-Karp

    这个算法是基于FF方法,就是通过不断求残余网络的增广路来增广流量,直到找不到增广路为止.注意:每次找到增广路以后都要更新原网络.EK算法通过BFS寻找源S到汇T的一条最短路径,因此时间复杂度是O(VE ...

  3. [转]Ubuntu上的包管理:dpkg,apt和aptitude

    一直以来对于ubuntu的包管理的概念就是apt-get,偶尔手动装个包就是dpkg -i,现在觉得是要系统地了解一下这几个包管理的命令. 原文转自: http://zhouliang.pro/201 ...

  4. Redis的安装(Centos)(转)

    1.1. 什么是redis Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库.它通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如 ...

  5. html5 文件拖拽上传

    本文首先发表在  码蜂笔记 : http://coderbee.net/index.php/web/20130703/266 html5 文件拖拽上传是个老话题了,网上有很多例子,我一开始的代码也是网 ...

  6. 检查Oracle 中死事务的语句

    SQL> SELECT KTUXEUSN, KTUXESLT, KTUXESQN, /* Transaction ID */ 2 KTUXESTA Status, KTUXECFL Flags ...

  7. ReentrantLock与synchronized的差别

    总的来说,lock更加灵活. 主要同样点:Lock能完毕synchronized所实现的全部功能 不同: 1.ReentrantLock功能性方面更全面,比方时间锁等候,可中断锁等候,锁投票等,因此更 ...

  8. 内核代码架构图 :systemtap函数选择点

  9. 5 - SQL Server 2008 之 四则运算、比较运算、逻辑运算及字符连接运算

    四则运算如下: --加减乘除(+.-.*.\.%)取余运算 SELECT --加法运算 AS 加法结果2, --减法运算 -2.5 AS 减法结果1, 15.5+5.5 AS 减法结果2, --乘法运 ...

  10. AndroidStudyDemo之Android4.x介绍

    Android4.x 思维导图 作者:李旺成 时间:2016年4月7日 AndroidStudyDemo 系列篇章开始了!!! AndroidStudyDemo 你值得拥有AndroidStudyDe ...