HDU 4010.Query on The Trees 解题报告
题意:
给出一颗树,有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 解题报告的更多相关文章
- 动态树(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 (动态树)(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在一棵树上, ...
- 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)
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(动态树)
题意 给定一棵 \(n\) 个节点的树,每个点有点权.完成 \(m\) 个操作,操作四两种,连接 \((x,y)\) :提 \(x\) 为根,并断 \(y\) 与它的父节点:增加路径 \((x,y)\ ...
- hdu 4010 Query on The Trees LCT
支持:1.添加边 x,y2.删边 x,y3.对于路径x,y上的所有节点的值加上w4.询问路径x,y上的所有节点的最大权值 分析:裸的lct...rev忘了清零死循环了两小时... 1:就是link操作 ...
- HDOJ 4010 Query on The Trees LCT
LCT: 分割.合并子树,路径上全部点的点权添加一个值,查询路径上点权的最大值 Query on The Trees Time Limit: 10000/5000 MS (Java/Others) ...
- 【LeetCode】951. Flip Equivalent Binary Trees 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcod ...
随机推荐
- 在代码中创建Drawable资源
如何在代码中创建圆环: 先看效果图 代码; import android.graphics.drawable.GradientDrawable; GradientDrawable circle = n ...
- 直接拿来用!最火的android开源项目(一)
不好意思尊重一下作者咯.详情见:csdn:http://www.csdn.net/article/2013-05-03/2815127-Android-open-source-projects
- 利用NSIS软件制作C#安装包
最近在做C#程序安装包,结果网上看到这个软件还是不错的,可以尝试以下. NSIS 是“Nullsoft 脚本安装系统”(Nullsoft Scriptable Installation System) ...
- Hadoop的文件读写操作流程
以下主要讲解了Hadoop的文件读写操作流程: 读文件 读文件时内部工作机制参看下图: 客户端通过调用FileSystem对象(对应于HDFS文件系统,调用DistributedFileSystem对 ...
- java基础(十三)常用类总结(三)
这里有我之前上课总结的一些知识点以及代码大部分是老师讲的笔记 个人认为是非常好的,,也是比较经典的内容,真诚的希望这些对于那些想学习的人有所帮助! 由于代码是分模块的上传非常的不便.也比较多,讲的也是 ...
- HDOJ 1716 排列2(next_permutation函数)
Problem Description Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数. Input 每组数据占一行,代表四张卡 ...
- bzoj 1923 [Sdoi2010]外星千足虫(高斯消元+bitset)
1923: [Sdoi2010]外星千足虫 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 634 Solved: 397[Submit][Status ...
- margin设置为负数
1.为负margin“平反” 我们在CSS中都会使用margin,但将margin设置成负数,那可能就不大好处理了.在网页设计中,人们对负margin用法的态度大相径庭,有的人非常喜欢,而有的人则认为 ...
- qut训练题解-2016-9-4个人赛
题目链接:http://acm.hust.edu.cn/vjudge/contest/131124#overview 贴了链接这里就不上原题的描述了. A: B: 分析:这里用到简单的拓扑排序的算法. ...
- ios策略模式应用
策略模式应用大量应用于解决巨型switch-case if-else..... 具体使用方法 : 策略基类(BaseStrategy)包含一个虚算法,所有子类实现虚算法 容器类含有一个指向策略基类的 ...