HDU 4010 Query on The Trees
2016-03-03 20:32
453 查看
[align=left]Problem Description[/align]
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!
[align=left]Input[/align]
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.
[align=left]Output[/align]
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.
[align=left]Sample Input[/align]
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
[align=left]Sample Output[/align]
3
-1
7
[b]LCT模板[/b]
View Code
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!
[align=left]Input[/align]
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.
[align=left]Output[/align]
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.
[align=left]Sample Input[/align]
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
[align=left]Sample Output[/align]
3
-1
7
[b]LCT模板[/b]
#include<cstdio> #include<cstring> #include<algorithm> #define MN 300001 using namespace std; int p,ca,f; inline int read(){ p=0;ca=getchar();f=1; while(ca<'0'||ca>'9') {if (ca=='-') f=-1;ca=getchar();} while(ca>='0'&&ca<='9') p=p*10+ca-48,ca=getchar(); return p*f; } struct na{ int y,ne; }b[MN*2]; int fa[MN],n,m,x,y,ch[MN][2],top,st[MN],key[MN],ma[MN],c[MN],l[MN],r[MN],num; bool rev[MN]; inline int max(int a,int b){return a>b?a:b;} inline bool isroot(int x){ return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; } inline void pu(int x,int w){ if (!x) return; c[x]+=w;key[x]+=w;ma[x]+=w; } inline void pd(int x){ if (c[x]){ pu(ch[x][0],c[x]);pu(ch[x][1],c[x]); c[x]=0; } if (rev[x]){ rev[x]=0;rev[ch[x][0]]^=1;rev[ch[x][1]]^=1; swap(ch[x][0],ch[x][1]); } } inline void up(int x){ pd(x);pd(ch[x][0]);pd(ch[x][1]); ma[x]=max(max(ma[ch[x][0]],ma[ch[x][1]]),key[x]); } inline void rot(int x){ int y=fa[x],kind=ch[y][1]==x; if(!isroot(y)) ch[fa[y]][ch[fa[y]][1]==y]=x; fa[x]=fa[y]; fa[y]=x; ch[y][kind]=ch[x][!kind]; fa[ch[y][kind]]=y; ch[x][!kind]=y; up(y);up(x); } inline void splay(int x){ register int i;top=1;st[1]=x; for (i=x;!isroot(i);i=fa[i]) st[++top]=fa[i]; for (i=top;i;i--) up(st[i]); while(!isroot(x)){ if (isroot(fa[x])) rot(x);else if ((ch[fa[fa[x]]][1]==fa[x])==(ch[fa[x]][1]==x)) rot(fa[x]),rot(x);else rot(x),rot(x); } } inline void acc(int u){ int x=0; while(u){ splay(u); ch[u][1]=x; u=fa[x=u]; } } inline int find(int x){ acc(x);splay(x); while(ch[x][0]) x=ch[x][0]; return x; } inline bool qu(int x,int y){ if (find(x)==find(y)) return 1;else return 0; } inline void re(int x){ acc(x);splay(x);rev[x]^=1; } inline void in(int x,int y){ if (qu(x,y)){printf("-1\n");return;} re(x);acc(y); ch[y][1]=x;fa[x]=y; } inline void del(int x,int y){ if (!qu(x,y)||x==y){printf("-1\n");return;} re(x);acc(y);splay(y);ch[y][0]=fa[ch[y][0]]=0; } inline void change(int x,int y,int w){ if (!qu(x,y)){printf("-1\n");return;} re(x);acc(y);splay(y);pu(y,w); } inline int que(int x,int y){ if (!qu(x,y)) return -1; re(x);acc(y);splay(y); return ma[y]; } inline void inl(int x,int y){ num++; if (!l[x]) l[x]=num;else b[r[x]].ne=num; b[num].y=y;b[num].ne=0;r[x]=num; } inline void dfs(int x){ for (int i=l[x];i;i=b[i].ne) if (!fa[b[i].y]){ fa[b[i].y]=x; dfs(b[i].y); } } int o; int main(){ register int i; ma[0]=-1e9; while(scanf("%d",&n)!=EOF){ num=0; memset(fa,0,sizeof(fa)); memset(ch,0,sizeof(ch)); memset(c,0,sizeof(c)); memset(l,0,sizeof(l)); memset(rev,0,sizeof(rev)); for (i=1;i<n;i++){ x=read();y=read(); inl(x,y); inl(y,x); } for(i=1;i<=n;i++) ma[i]=key[i]=read(); fa[1]=1; dfs(1); fa[1]=0; m=read(); while(m--){ o=read(); int x,y,z;x=read();y=read(); if (o==1) in(x,y);else if (o==2) del(x,y);else if (o==3) z=read(),change(y,z,x);else printf("%d\n",que(x,y)); } printf("\n"); } }
View Code
相关文章推荐
- String、StringBuilder、StringBuffer的区别
- SPOJ QTREE - Query on a tree
- question_015-JAVA之Map的遍历方式
- String 与StringBuilder
- Class Of Marquee Scroll通用不间断滚动JS脚本
- ProcessBuilder中如何为命令行传参
- UI控件初始化问题:initWithFrame和initWithCoder、aweakFromNib的执行
- 谈谈UIView的几个layout方法-layoutSubviews、layoutIfNeeded、setNeedsLayout
- spoj 2319 BIGSEQ - Sequence
- Sphinx Building Docs in horizon
- UIView - animateWithDuration 手势动画 使用详解
- 关于IList、IQueryable、IEnumerable与Func、Expression的关系
- UGUI官方案例—下载
- VirtualBox注册虚拟机时,Cannot register the image ‘C:\Proqram FiIes\OracIe\VirtuaIBox\VBoxGuestAdditionsiso
- Leetcode: 232. Implement Queue using Stacks(JAVA)
- HSEARCH000135: Unable to guess FieldBridge for...
- GUILayout 布局
- Ant build.xml中应该只包含一个target标签
- STL_deque
- Java中break return continue 区别