Query on The Trees

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 4091    Accepted Submission(s): 1774

Problem Description
We have met so many problems on the tree, so today we will have a query problem on a set of trees. 
There are N nodes, each node will have a unique weight Wi. We will have four kinds of operations on it and you should solve them efficiently. Wish you have fun!

 
Input
There are multiple test cases in our dataset. 
For each case, the first line contains only one integer N.(1 ≤ N ≤ 300000) The next N‐1 lines each contains two integers x, y which means there is an edge between them. It also means we will give you one tree initially. 
The next line will contains N integers which means the weight Wi of each node. (0 ≤ Wi ≤ 3000) 
The next line will contains an integer Q. (1 ≤ Q ≤ 300000) The next Q lines will start with an integer 1, 2, 3 or 4 means the kind of this operation. 
1. Given two integer x, y, you should make a new edge between these two node x and y. So after this operation, two trees will be connected to a new one. 
2. Given two integer x, y, you should find the tree in the tree set who contain node x, and you should make the node x be the root of this tree, and then you should cut the edge between node y and its parent. So after this operation, a tree will be separate into two parts. 
3. Given three integer w, x, y, for the x, y and all nodes between the path from x to y, you should increase their weight by w. 
4. Given two integer x, y, you should check the node weights on the path between x and y, and you should output the maximum weight on it. 
 
Output
For each query you should output the correct answer of it. If you find this query is an illegal operation, you should output ‐1. 
You should output a blank line after each test case. 
 
Sample Input
5
1 2
2 4
2 5
1 3
1 2 3 4 5
6
4 2 3
2 1 2
4 2 3
1 3 5
3 2 1 4
4 1 4
 
Sample Output
3
-1
7

Hint

We define the illegal situation of different operations:
In first operation: if node x and y belong to a same tree, we think it's illegal.
In second operation: if x = y or x and y not belong to a same tree, we think it's illegal.
In third operation: if x and y not belong to a same tree, we think it's illegal.
In fourth operation: if x and y not belong to a same tree, we think it's illegal.

 
Source
 
Recommend
lcy
 

题解:

LCT的子树问题。

找到每个点所在的原始树(不是Splay树)的根。

又是子树判断最麻烦。。。

 #include<bits/stdc++.h>
using namespace std;
#define MAXN 300010
#define INF 1e9
struct node
{
int left,right,val,mx;
}tree[MAXN];
struct NODE
{
int begin,end,next;
}edge[MAXN*];
int father[MAXN],rev[MAXN],tag[MAXN],U[MAXN],V[MAXN],Stack[MAXN],Head[MAXN],cnt;
void addedge(int bb,int ee)
{
edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].next=Head[bb];Head[bb]=cnt;
}
void addedge1(int bb,int ee)
{
addedge(bb,ee);addedge(ee,bb);
}
int read()
{
int s=,fh=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')fh=-;ch=getchar();}
while(ch>=''&&ch<=''){s=s*+(ch-'');ch=getchar();}
return s*fh;
}
int isroot(int x)
{
return tree[father[x]].left!=x&&tree[father[x]].right!=x;
}
void pushdown(int x)
{
int l=tree[x].left,r=tree[x].right;
if(rev[x]!=)
{
rev[x]^=;rev[l]^=;rev[r]^=;
swap(tree[x].left,tree[x].right);
}
if(tag[x]!=)
{
/*tag[l]+=tag[x];tag[r]+=tag[x];
tree[l].val+=tag[x];tree[r].val+=tag[x];
tree[l].mx+=tag[x];tree[r].mx+=tag[x];*/
if(l!=){tag[l]+=tag[x];tree[l].val+=tag[x];tree[l].mx+=tag[x];}
if(r!=){tag[r]+=tag[x];tree[r].val+=tag[x];tree[r].mx+=tag[x];}
tag[x]=;
}
}
void Pushup(int x)
{
int l=tree[x].left,r=tree[x].right;
tree[x].mx=max(max(tree[l].mx,tree[r].mx),tree[x].val);
}
void rotate(int x)
{
int y=father[x],z=father[y];
if(!isroot(y))
{
if(tree[z].left==y)tree[z].left=x;
else tree[z].right=x;
}
if(tree[y].left==x)
{
father[x]=z;father[y]=x;tree[y].left=tree[x].right;tree[x].right=y;father[tree[y].left]=y;
}
else
{
father[x]=z;father[y]=x;tree[y].right=tree[x].left;tree[x].left=y;father[tree[y].right]=y;
}
Pushup(y);Pushup(x);
}
void splay(int x)
{
int top=,i,y,z;Stack[++top]=x;
for(i=x;!isroot(i);i=father[i])Stack[++top]=father[i];
for(i=top;i>=;i--)pushdown(Stack[i]);
while(!isroot(x))
{
y=father[x];z=father[y];
if(!isroot(y))
{
if((tree[y].left==x)^(tree[z].left==y))rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x)
{
int last=;
while(x!=)
{
splay(x);
tree[x].right=last;Pushup(x);
last=x;x=father[x];
}
}
void makeroot(int x)
{
access(x);splay(x);rev[x]^=;
}
void link(int u,int v)
{
/*access(u);*/makeroot(u);father[u]=v;//splay(u);
}
void cut(int u,int v)
{
/*access(u);*/makeroot(u);access(v);splay(v);/*father[u]=tree[v].left=0;*/father[tree[v].left]=;tree[v].left=;Pushup(v);
}
int findroot(int x)
{
access(x);splay(x);
while(tree[x].left!=)x=tree[x].left;
return x;
}
int main()
{
int n,i,w,x,y,fh,Q,top=,u,j,v;
while(scanf("%d",&n)!=EOF)
{
top=;
for(i=;i<=n;i++)tree[i].val=tree[i].mx=tree[i].left=tree[i].right=rev[i]=tag[i]=father[i]=;
tree[].mx=-INF;
memset(Head,-,sizeof(Head));cnt=;
for(i=;i<n;i++)
{
U[i]=read();V[i]=read();
addedge1(U[i],V[i]);
}
Stack[++top]=;
for(i=;i<=top;i++)
{
u=Stack[i];
for(j=Head[u];j!=-;j=edge[j].next)
{
v=edge[j].end;
if(v!=father[u])
{
father[v]=u;
Stack[++top]=v;
}
}
}
for(i=;i<=n;i++)tree[i].mx=tree[i].val=read();
//for(i=1;i<n;i++)link(U[i],V[i]);
Q=read();
for(i=;i<=Q;i++)
{
fh=read();
if(fh==)
{
x=read();y=read();
if(findroot(x)!=findroot(y))link(x,y);
else {printf("-1\n");continue;}
}
else if(fh==)
{
x=read();y=read();
if(findroot(x)==findroot(y)&&x!=y)
{
/*makeroot(x);*/cut(x,y);
//access(y);access(father[y]);splay(father[y]);father[y]=tree[father[y]].left=0;
}
else {printf("-1\n");continue;}
}
else if(fh==)
{
w=read();x=read();y=read();
if(findroot(x)==findroot(y))
{
makeroot(x);access(y);splay(y);
tag[y]+=w;tree[y].mx+=w;tree[y].val+=w;
}
else {printf("-1\n");continue;}
}
else
{
x=read();y=read();
makeroot(x);access(y);splay(y);
if(findroot(x)!=findroot(y)){printf("-1\n");continue;}
printf("%d\n",tree[y].mx);
}
}
printf("\n");
}
return ;
}

Hdu 4010-Query on The Trees LCT,动态树的更多相关文章

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

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

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

  3. hdu 4010 Query on The Trees LCT

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

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

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

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

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

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

  7. HDOJ 4010 Query on The Trees LCT

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

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

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

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

随机推荐

  1. 分享red hat linux 6上安装oracle11g时遇到的gcc: error trying to exec 'cc1': execvp: No such file or directory的问题处理过程

    安装环境:Red Hat Linux 6.5_x64.oracle11g 64bit 报错详情: 安装到68%时弹窗报错: 调用makefile '/test/app/Administrators/p ...

  2. CI 笔记,使用 json的参考文档(废弃)

    Json的处理转换, Json转换步骤, a)         先设置json为空字符串, b)         While循环,遍历, While(!!$row = mysql_fetch_arra ...

  3. iOS 开发工具

    Github 社区 https://github.com/ iOS 开发类库 http://www.code4app.com/thread-7831-1-1.html (出处: Code4App-iO ...

  4. 集成支付宝报一堆warning: (arm64) /Users/scmbuild/workspace/standard-pay/.....警告问题解决办法亲测可行!

  5. js小分享

    之前实现一些js代码时,总觉得无法下手,所以最近在学习一下特别细的知识点,分享笔记.嘻嘻,偷个小懒,我把自己的笔记拍个照片就不打字了.嘎嘎,放心放心,自觉得字写的还算ok的啦- 表示家里的老弟玩游戏, ...

  6. 利用CART算法建立分类回归树

    常见的一种决策树算法是ID3,ID3的做法是每次选择当前最佳的特征来分割数据,并按照该特征所有可能取值来切分,也就是说,如果一个特征有四种取值,那么数据将被切分成4份,一旦按某特征切分后,该特征在之后 ...

  7. windows上SVN服务器以及客户端TortoiseSVN的安装配置

    (1)svn的安装 1. 下载软件:Setup-Subversion-1.7.5.msi,安装就很容易了,一路NEXT 2. 把SVN的bin文件夹路径添加到环境变量中 把svn安装目录下的bin路径 ...

  8. 【原创】Android 从一个Activity跳转到另外一个Activity

    Android四大组件activity使用,实现两个activity之间的跳转 基本流程:创建两个activity-将其中一个activity中组件作为事件源-通过组件事件的处理借助intent对象实 ...

  9. php邮箱找回密码功能

    原理很简单: 用户找回密码的时候,填写用户名,程序得到用户名便可以去数据库取出用户对应的密码以及当时填写的邮箱, 根据用户名和密码生成一个key=md5(username+password),然后$s ...

  10. vim设置

    折腾一下vim http://www.cnblogs.com/zhangsf/archive/2013/06/13/3134409.html