题意:

  给出一颗树,有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. [学习整理]eclipe/MyEclipse:重要的快捷键

    一.查看大工程代码最重要的几个快捷键 其实有一些,直接在编辑器页面内右键也可查看相应的快捷键(比如F3,F4,Ctrl+O,Ctrl+T),但有些比较好用的快捷键,并不能能直接或方便地在eclipse ...

  2. Rest中的XML与JSON的序列化与反序列化

    #region 获取XML的序列化和反序列化 /// <summary> /// 对象进行序列化生成XML /// </summary> /// <typeparam n ...

  3. C++之函数指针

    函数指针常用的有三类 1.指向普通函数的函数指针 2.指向类中静态成员函数的函数指针 3.指向类的成员函数的函数指针 一.指向普通函数的函数指针 #include <iostream> u ...

  4. mac下的改装人生——关于机械键盘

    这几天好像弄了很多关于机械键盘的东西,我自己的这块键盘也已经慢慢熟悉了,感觉打字超级爽哈,然后看了很多网上关于机械键盘的帖子,也看了很多教程,在Amazon和Taobao看了很多键盘的价位,前几天还试 ...

  5. MongoDB性能优化指南

    一.索引 MongoDB 提供了多样性的索引支持,索引信息被保存在system.indexes 中,且默认总是为_id创建索引,它的索引使用基本和MySQL 等关系型数据库一样.其实可以这样说说,索引 ...

  6. mahout算法源码分析之Collaborative Filtering with ALS-WR拓展篇

    Mahout版本:0.7,hadoop版本:1.0.4,jdk:1.7.0_25 64bit. 额,好吧,心头的一块石头总算是放下了.关于Collaborative Filtering with AL ...

  7. ios策略模式应用

    策略模式应用大量应用于解决巨型switch-case  if-else..... 具体使用方法 : 策略基类(BaseStrategy)包含一个虚算法,所有子类实现虚算法 容器类含有一个指向策略基类的 ...

  8. Scrapy的shell命令(转)

    scrapy python MrZONT                        2015年08月29日发布                                            ...

  9. Windows 下OpenSSL 安装

    安装环境: .操作系统:Windows XP SP2 2.C++编译器:VC++ 6.0 下载: 下载ActivePerl  5.10.1.1007(最新的版本或较低的版本也可以): 下载地址:htt ...

  10. leetcode-1 Two Sum 找到数组中两数字和为指定和

     问题描写叙述:在一个数组(无序)中高速找出两个数字,使得两个数字之和等于一个给定的值.如果数组中肯定存在至少一组满足要求. <剑指Offer>P214(有序数组) <编程之美& ...