题意:

  给出一颗树,有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. HDU-1963

    http://acm.hdu.edu.cn/showproblem.php?pid=1963 完全背包. 题意:给出初始资金,还有年数,然后给出每个物品的购买价格与每年获得的利益,要求在给出的年份后所 ...

  2. HDOJ 2011 多项式求和

    Problem Description 多项式的描述如下: 1 - 1/2 + 1/3 - 1/4 + 1/5 - 1/6 + - 现在请你求出该多项式的前n项的和. Input 输入数据由2行组成, ...

  3. asp json

    <script language="JScript" runat="Server">function toObject(json) {    eva ...

  4. Shadow Register 是什么?

    ARM处理器有个Shadow Register的概念,查了很多资料,语焉不详,究竟是什么意思呢? 这其实是个和硬件有关的概念. 有些register是2层的,第一层是供CPU访问,第二层供Hw访问. ...

  5. 自主架设VOIP系统

    my.oschina.net/fcboys/blog/2695 FXS (Foreign Exchange Station) FXS is an interface which drives a te ...

  6. [转载]opencv MSER

    最大稳定极值区域(MSER-Maximally Stable Extremal Regions)可以用于图像的斑点区域检测.该算法最早是由Matas等人于2002年提出,它是基于分水岭的概念. MSE ...

  7. Intersecting Lines - POJ 1269(判断平面上两条直线的关系)

    分析:有三种关系,共线,平行,还有相交,共线和平行都可以使用叉积来进行判断(其实和斜率一样),相交需要解方程....在纸上比划比划就出来了....   代码如下: ================== ...

  8. Android 解决ScrollView下嵌套ListView进页面不在顶部的问题

    以下为整理: 方法1 刚开始还可以,后来再调试时就不行了. 为了解决scrollview和listview冲突  设置了listview的高度   结果进页面就不是在顶部了 . 解决方案1:Scrol ...

  9. css三角形绘制

    三角形演变: 1.将一个块元素的宽.高都设置为0,再设置边框样式,得如下效果图(绿色部分): 样式: {;;border: 35px solid #7de87d;} 通过此样式得到的是一个正方形. 2 ...

  10. MySQL Replication主从复制

    MySQL Replication:NySQL复制,MySQL的复制默认为异步工作模式   mysql的复制功能是mysql内置的,装上它之后就具备了这个功能,而mysql复制是mysql实现大规模高 ...