动态树(LCT):HDU 4010 Query on The Trees
Query on The Trees
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 4002 Accepted Submission(s): 1749
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!
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.
You should output a blank line after each test case.
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
-1
7
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.
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- using namespace std;
- const int MAXN=;
- int fir[MAXN],nxt[MAXN<<],to[MAXN<<],cnt;
- int Max[MAXN],fa[MAXN],ch[MAXN][],flip[MAXN],add[MAXN],key[MAXN];
- bool rt[MAXN];
- void Push_up(int p)
- {
- Max[p]=max(key[p],max(Max[ch[p][]],Max[ch[p][]]));
- }
- void Add(int p,int d)
- {
- if(!p)return;
- key[p]+=d;
- Max[p]+=d;
- add[p]+=d;
- }
- void Flip(int p)
- {
- if(!p)return;
- swap(ch[p][],ch[p][]);
- flip[p]^=;
- }
- void Push_down(int p)
- {
- if(add[p]){
- Add(ch[p][],add[p]);
- Add(ch[p][],add[p]);
- add[p]=;
- }
- if(flip[p]){
- Flip(ch[p][]);
- Flip(ch[p][]);
- flip[p]=;
- }
- }
- void Rotate(int x)
- {
- int y=fa[x],g=fa[y],c=ch[y][]==x;
- ch[y][c]=ch[x][c^];fa[ch[y][c]]=y;
- ch[x][c^]=y;fa[y]=x;fa[x]=g;
- if(rt[y])
- rt[y]=false,rt[x]=true;
- else
- ch[g][ch[g][]==y]=x;
- Push_up(y);
- }
- void P(int p)
- {
- if(!rt[p])P(fa[p]);
- Push_down(p);
- }
- void Splay(int x)
- {
- P(x);
- for(int y=fa[x];!rt[x];Rotate(x),y=fa[x])
- if(!rt[y])
- Rotate((ch[fa[y]][]==y)==(ch[y][]==x)?y:x);
- Push_up(x);
- }
- bool Judge(int x,int y)
- {
- while(fa[x])x=fa[x];
- while(fa[y])y=fa[y];
- return x==y;
- }
- void Access(int x)
- {
- int y=;
- while(x)
- {
- Splay(x);
- rt[ch[x][]]=true;
- rt[ch[x][]=y]=false;
- Push_up(x);
- x=fa[y=x];
- }
- }
- void Lca(int &x,int &y)
- {
- Access(y);y=;
- while(true)
- {
- Splay(x);
- if(!fa[x])return;
- rt[ch[x][]]=true;
- rt[ch[x][]=y]=false;
- Push_up(x);
- x=fa[y=x];
- }
- }
- void Make_root(int x)
- {
- Access(x);
- Splay(x);
- Flip(x);
- }
- void Link(int x,int y)
- {
- if(Judge(x,y)){
- printf("-1\n");
- return;
- }
- Make_root(x);
- Splay(x);
- fa[x]=y;
- }
- void Cut(int x,int y)
- {
- if(x==y||!Judge(x,y)){
- printf("-1\n");
- return;
- }
- Make_root(x);
- Splay(y);
- fa[ch[y][]]=fa[y];
- fa[y]=;
- rt[ch[y][]]=true;
- ch[y][]=;
- Push_up(y);
- }
- void Change(int x,int y,int d)
- {
- if(!Judge(x,y)){
- printf("-1\n");
- return;
- }
- Lca(x,y);
- Add(ch[x][],d);
- Add(y,d);
- key[x]+=d;
- Push_up(x);
- }
- void Query(int x,int y)
- {
- if(!Judge(x,y)){
- printf("-1\n");
- return;
- }
- Lca(x,y);
- printf("%d\n",max(key[x],max(Max[ch[x][]],Max[y])));
- }
- void addedge(int a,int b)
- {
- nxt[++cnt]=fir[a];to[cnt]=b;fir[a]=cnt;
- }
- void DFS(int node,int pre)
- {
- for(int i=fir[node];i;i=nxt[i])
- if(to[i]!=pre){
- fa[to[i]]=node;
- DFS(to[i],node);
- }
- }
- void Init()
- {
- memset(fir,,sizeof(fir));
- memset(ch,,sizeof(ch));
- memset(fa,,sizeof(fa));
- memset(rt,-,sizeof(rt));
- memset(flip,,sizeof(flip));
- memset(add,,sizeof(add));
- cnt=;Max[]=-;
- }
- int main()
- {
- int Q,n,x,y,d,k;
- while(~scanf("%d",&n))
- {
- Init();
- for(int i=;i<n;i++){
- scanf("%d%d",&x,&y);
- addedge(x,y);
- addedge(y,x);
- }
- for(int i=;i<=n;i++){
- scanf("%d",&key[i]);
- Max[i]=key[i];
- }
- DFS(,);
- scanf("%d",&Q);
- while(Q--)
- {
- scanf("%d",&k);
- if(k==){
- scanf("%d%d",&x,&y);
- Link(x,y);
- }
- else if(k==){
- scanf("%d%d",&x,&y);
- Cut(x,y);
- }
- else if(k==){
- scanf("%d%d%d",&d,&x,&y);
- Change(x,y,d);
- }
- else if(k==){
- scanf("%d%d",&x,&y);
- Query(x,y);
- }
- }
- printf("\n");
- }
- return ;
- }
动态树(LCT):HDU 4010 Query on The Trees的更多相关文章
- 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 解题报告
题意: 给出一颗树,有4种操作: 1.如果x和y不在同一棵树上则在xy连边 2.如果x和y在同一棵树上并且x!=y则把x换为树根并把y和y的父亲分离 3.如果x和y在同一棵树上则x到y的路径上所有的点 ...
- 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(动态树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4010 题意:一棵树,四种操作: (1)若x和y不在一棵树上,将x和y连边: (2)若x和y在一棵树上, ...
- 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操作 ...
- 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 5398 动态树LCT
GCD Tree Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- hdu 5002 (动态树lct)
Tree Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
随机推荐
- 【Android】android镜像翻转
Android镜像翻转指的是将屏幕进行水平的翻转,达到所有内容显示都会反向的效果,就像是在镜子中看到的界面一样.这种应用的使用场景相对比较受限,主要用在一些需要使用Android手机界面进行镜面投影的 ...
- (tomcat访问不了的两种解决方法)Bad Request(Invalid Hostname)
显示这个页面的时候一般有几中解决方法: 第一种就是如下图所示的方法: 具体步骤是: 1.也就是左下角win的“运行”中输入cmd进入doc窗口中 2.输入代码:netstat -ano 3.找到占用8 ...
- WPF MediaElement.Position属性
Position 属性定义:获取或设置媒体播放时间的当前进度位置. // // 摘要: // 通过媒体播放时获取或设置进度的当前位置. // // 返回结果: // 媒体时自以来的.默认值为 00:0 ...
- TFS 服务器更换后工作区无法绑定
需要删除工作区,删除命令如下 tf workspace /delete 工作区名;创建的用户 /server:TFS服务器 例 tf workspace /delete WHQ-PC;whq /ser ...
- HBase0.98.1 通过协调器进行表的行数统计
1. 启用表aggregation,只对特定的表生效.通过HBase Shell 来实现 (1)disable指定表.hbase> disable 'student' (2)添加aggregat ...
- rdlc报表
也是第一次接触报表这个东西.现在在我理解,报表无非就是两个内容,格式和数据. 格式没有多少了解,就记录了,以后再续.数据的绑定和结果的显示是怎么实现的呢? 今天的主角就是rdlc这个文件和Report ...
- table强制不换行
用iframe做了一个查询,里面有一个表格,结果当页面内容多的时候挤在了一起. 上图:
- 【POJ2155】【二维树状数组】Matrix
Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the ...
- 第二篇、Maven快速上手
1.目标 该篇主要是为了快速利用maven来构建工程,maven作为项目管理的工具已经得到极大程度的应用,很多开源项目都用maven来构建.如何建立 一个maven工程,如何导入别人的maven工程, ...
- URPF 简单流程
主要功能是防止基于源地址欺骗的网络攻击. 路由器接口一旦使能URPF功能,当该接口收到数据报文时,首先会对数据报文的源地址进行合法性检查,对于源地址合法性检查通过的报文,才会进一步查找去往目的地址的转 ...