HDU 4010 Query on The Trees(动态树)
题目链接: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(动态树)的更多相关文章
- HDU 4010 Query on The Trees (动态树)(Link-Cut-Tree)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4010 题意; 先给你一棵树,有 \(4\) 种操作: 1.如果 \(x\) 和 \(y\) 不在同一 ...
- 动态树(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 ...
- 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(动态树)
题意 给定一棵 \(n\) 个节点的树,每个点有点权.完成 \(m\) 个操作,操作四两种,连接 \((x,y)\) :提 \(x\) 为根,并断 \(y\) 与它的父节点:增加路径 \((x,y)\ ...
- 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 4010 Query on The Trees LCT
支持:1.添加边 x,y2.删边 x,y3.对于路径x,y上的所有节点的值加上w4.询问路径x,y上的所有节点的最大权值 分析:裸的lct...rev忘了清零死循环了两小时... 1:就是link操作 ...
- HDOJ 4010 Query on The Trees LCT
LCT: 分割.合并子树,路径上全部点的点权添加一个值,查询路径上点权的最大值 Query on The Trees Time Limit: 10000/5000 MS (Java/Others) ...
- 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 ...
随机推荐
- CCI_chapter 1
1.1Implement an algorithm to determine if a string has all unique characters What if you can not us ...
- ASP.NET页面事件顺序
当一个页面请求发送到WEB服务器时,不论该事件是由页面提交还是由页面重定向而激发的,页面在其被创建到释放的过程中都会运行一系列的事件.一个ASP.NET页面从悲怆见到释放的过程包含10个事件. (1) ...
- simulate windows postmessage or keydown
2 ways: 1. under TForm: if assigned(focused) then Focused.keydown(key,keychar,[]); 2. using s ...
- WPF:如何实现单实例的应用程序(Single Instance)
原文:WPF:如何实现单实例的应用程序(Single Instance) 好吧,这是我将WPF与Windows Forms进行比较的系列文章的第四篇,讨论一下如何实现单实例(single instan ...
- SQL使用单引号
SQL> select 'xxxx'oooo' from dual; ERROR: ORA-01756: quoted string not properly terminated SQL> ...
- wan口mac=lan口mac加一,wlan是lan口mac加二
(1)路由器有两个mac地址,一个用于外网(wan),一个用于内网(wlan和lan): (2)一般路由器上面或者配置路由器的网页上面只标注外网的mac地址: (3)内网的mac地址和外网mac地址一 ...
- poj1881:素因子分解+素数测试
很好的入门题 先测试是否为素数,若不是则进行素因子分解,算法详见总结贴 miller robin 和pollard rho算法 AC代码 #include <iostream> #incl ...
- <php>Ajax基本格式
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8&quo ...
- Entify Framewrok - LINQ简单使用
1.如何使用Join: http://www.devcurry.com/2011/01/join-example-in-linq-and-c.html
- python socket学习
import socket localip=socket.gethostbyname(socket.gethostname()) print (localip) iplist=socket.getho ...