题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4010

题意:一棵树,四种操作:

(1)若x和y不在一棵树上,将x和y连边;

(2)若x和y在一棵树上,将x变成树根,将y从x树上分离;

(3)若x和y在一棵树上,将x到y路径上的所有值增加det;

(4)若x和y在一棵树上,输出x到y路径上的最大值。

思路:1操作用link维护,2操作用cut,34操作先split(x,y),然后对y做tag,并且记录路径的max值。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
int tot,go[],next[],first[];
int ch[][],rev[],tag[],q[];
int st[],mx[],fa[],v[];
bool pd(int x){
return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;
}
void insert(int x,int y){
tot++;go[tot]=y;next[tot]=first[x];first[x]=tot;
}
void addedge(int x,int y){
insert(x,y);insert(y,x);
}
void pushdown(int x){
int l=ch[x][],r=ch[x][];
if (rev[x]){
rev[x]^=;rev[l]^=;rev[r]^=;
std::swap(ch[x][],ch[x][]);
}
if (tag[x]){
if (l) tag[l]+=tag[x],v[l]+=tag[x],mx[l]+=tag[x];
if (r) tag[r]+=tag[x],mx[r]+=tag[x],v[r]+=tag[x];
tag[x]=;
}
}
void updata(int x){
int l=ch[x][],r=ch[x][];
mx[x]=std::max(v[x],std::max(mx[l],mx[r]));
}
void rotate(int x){
int y=fa[x],z=fa[y],l,r;
if (ch[y][]==x) l=;else l=;r=l^;
if (!pd(y)){
if (ch[z][]==y) ch[z][]=x;else ch[z][]=x;
}
fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
ch[y][l]=ch[x][r];ch[x][r]=y;
updata(y);updata(x);
}
void splay(int x){
int top=;st[++top]=x;
for (int i=x;!pd(i);i=fa[i])
st[++top]=fa[i];
for (int i=top;i;i--)
pushdown(st[i]);
while (!pd(x)){
int y=fa[x],z=fa[y];
if (!pd(y)){
if (ch[y][]==x^ch[z][]==y) rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x){
for (int t=;x;t=x,x=fa[x]){
splay(x);
ch[x][]=t;
updata(x);
}
}
void makeroot(int x){
access(x);splay(x);rev[x]^=;
}
void cut(int x,int y){
makeroot(x);access(y);splay(y);ch[y][]=fa[ch[y][]]=;updata(y);
}
void link(int x,int y){
makeroot(x);
fa[x]=y;
}
int find(int x){
access(x);splay(x);
while (ch[x][]) x=ch[x][];
return x;
}
void add(int x,int y,int val){
makeroot(x);access(y);splay(y);
mx[y]+=val;v[y]+=val;tag[y]+=val;
}
int main(){
int n,x,y,m,opt,w;
while (scanf("%d",&n)!=EOF){
mx[]=-;
for (int i=;i<=n;i++)
mx[i]=tag[i]=rev[i]=v[i]=ch[i][]=ch[i][]=fa[i]=;
memset(first,,sizeof first);tot=;
for (int i=;i<n;i++){
scanf("%d%d",&x,&y);
addedge(x,y);
}
for (int i=;i<=n;i++){
scanf("%d",&v[i]);
mx[i]=v[i];
}
int top=;
q[top]=;
for (int k=;k<=top;k++){
for (int i=first[q[k]];i;i=next[i]){
int pur=go[i];
if (pur==fa[q[k]]) continue;
fa[pur]=q[k];
q[++top]=pur;
}
}
top=;
scanf("%d",&m);
while (m--){
scanf("%d",&opt);
if (opt==){
scanf("%d%d",&x,&y);
if (find(x)==find(y)) {puts("-1");continue;}
link(x,y);
}
else
if (opt==){
scanf("%d%d",&x,&y);
if (find(x)!=find(y)||x==y) {puts("-1");continue;}
cut(x,y);
}
else
if (opt==){
scanf("%d%d%d",&w,&x,&y);
if (find(x)!=find(y)){puts("-1");continue;}
add(x,y,w);
}
else
if (opt==)
{
scanf("%d%d",&x,&y);
if (find(x)!=find(y)){
printf("-1\n");
continue;
}
makeroot(x);access(y);splay(y);
printf("%d\n",mx[y]);
}
}
printf("\n");
}
}

HDU 4010 Query on The Trees(动态树)的更多相关文章

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

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

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

  3. HDU 4010.Query on The Trees 解题报告

    题意: 给出一颗树,有4种操作: 1.如果x和y不在同一棵树上则在xy连边 2.如果x和y在同一棵树上并且x!=y则把x换为树根并把y和y的父亲分离 3.如果x和y在同一棵树上则x到y的路径上所有的点 ...

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

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

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

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

  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. Hdu 4010-Query on The Trees LCT,动态树

    Query on The Trees Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Othe ...

随机推荐

  1. C#中使用命名管道进行进程通信的实例

    原文:C#中使用命名管道进行进程通信的实例 1 新建解决方案NamedPipeExample 在解决方案下面新建两个项目:Client和Server,两者的输出类型均为"Windows 应用 ...

  2. 计算机语言学习导论[C/C++]

    作者:@幻の上帝 1 前置条件语文其实挺重要,这个没问题,但容易被忽视.当然,如果不是经常要折腾文档,要求不高:但起码要能说清楚话.数学重要,主要是广度,作为快速学习相关领域知识的基础.深度上面可深可 ...

  3. spring注解方式 idea报could not autowire,eclipse却没有问题

    解决办法1: 从根本上解决: File-Project Structure 页面 Facets下删掉 Spring(直接右键Delete) 这个解答是对的.并不会降低安全性!!因为创建项目的时候,都是 ...

  4. smarty 内置函数if 等判断

    {if},{elseif},{else} Smarty的{if}条件判断和PHP的if 非常相似,只是增加了一些特性. 每个{if}必须有一个配对的{/if}. 也可以使用{else} 和 {else ...

  5. Oracle索引状态查询&索引重建

    --检查损坏索引 SELECT status, COUNT(*)   FROM dba_indexes  GROUP BY status UNION SELECT status, COUNT(*)   ...

  6. Java里的equals总结

    前段时间一直在工作中使用Java,由于有一些C++功底,于是简单看了一下Java相关的语法便开始编写代码,结果在创建一个自定义类,并将自定义类放入ArrayList中,之后查找ArrayList是否有 ...

  7. Lucene 高亮功能

    原文转载自: http://qindongliang1922.iteye.com/blog/1953409 高亮功能一直都是全文检索的一项非常优秀的模块,在一个标准的搜索引擎中,高亮的返回命中结果,几 ...

  8. [转] Trie树详解及其应用

    一.知识简介         最近在看字符串算法了,其中字典树.AC自动机和后缀树的应用是最广泛的了,下面将会重点介绍下这几个算法的应用.       字典树(Trie)可以保存一些字符串->值 ...

  9. genymotion+Oracle VM VirtualBox + eclipse + appium 脚本运行慢解决步骤

    genymotion+Oracle VM VirtualBox + eclipse + appium 脚本运行慢解决步骤 1.lenove 机器启动时按F1 进入bios 设置,设置cpu virtu ...

  10. 面试时遇到的SQL

    CustomerID DateTime ProductName Price C001 2014-11-20 16:02:59 123 PVC 100 C001 2014-11-19 16:02:59 ...