Query on The Trees(hdu 4010)
题意:
给出一颗树,有4种操作:
1、如果x和y不在同一棵树上则在xy连边
2、如果x和y在同一棵树上并且x!=y则把x换为树根并把y和y的父亲分离
3、如果x和y在同一棵树上则x到y的路径上所有的点权值+w
4、如果x和y在同一棵树上则输出x到y路径上的最大值
/*
本来一道很水的LCT,结果hdu的提交页面被我刷屏了。。。
还是too young too simple啊,刚开始不知道多组数据,提交了N次,然后又因为下面的赋值问题提交了N++次。
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 300010
#define inf 1000000000
using namespace std;
int fa[N],son[N][],x[N],y[N],val[N],mx[N],tag[N],rev[N],st[N],n,m;
void pushdown(int x){
int l=son[x][],r=son[x][];
if(rev[x]){
swap(son[x][],son[x][]);
rev[l]^=;rev[r]^=;rev[x]^=;
}
if(tag[x]){
if(l){tag[l]+=tag[x];val[l]+=tag[x];mx[l]+=tag[x];}
if(r){tag[r]+=tag[x];val[r]+=tag[x];mx[r]+=tag[x];}
tag[x]=;
}
}
void pushup(int x){
int l=son[x][],r=son[x][];
mx[x]=max(val[x],max(mx[l],mx[r]));
}
bool isroot(int x){
return son[fa[x]][]!=x&&son[fa[x]][]!=x;
}
void rotate(int x){
int y=fa[x],z=fa[y],l,r;
if(son[y][]==x)l=;else l=;r=l^;
if(!isroot(y)){
if(son[z][]==y) son[z][]=x;
else son[z][]=x;
}
fa[x]=z;fa[y]=x;fa[son[x][r]]=y;
son[y][l]=son[x][r];son[x][r]=y;
pushup(y);pushup(x);
}
void splay(int x){
int top=;st[++top]=x;
for(int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
for(int i=top;i;i--) pushdown(st[i]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if(son[z][]==y^son[y][]==x)rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x){
int t=;
while(x){
splay(x);
son[x][]=t;
pushup(x);
t=x;x=fa[x];
}
}
void makeroot(int x){
access(x);
splay(x);
rev[x]^=;
}
void join(int x,int y){
makeroot(x);
fa[x]=y;
}
void cut(int x,int y){
makeroot(x);
access(y);
splay(y);
//fa[son[y][0]]=son[y][0]=0;
//我可能学了假的c++,连从右到左赋值都不知道!!!
son[y][]=fa[son[y][]]=;
pushup(y);
}
int find(int x){
access(x);splay(x);
int y=x;
while(son[y][]) y=son[y][];
return y;
}
void work(){
mx[]=-inf;
for(int i=;i<n;i++)scanf("%d%d",&x[i],&y[i]);
for(int i=;i<=n;i++)scanf("%d",&val[i]),mx[i]=val[i];
for(int i=;i<n;i++)join(x[i],y[i]);
scanf("%d",&m);
int opt,x,y,w;
for(int i=;i<=m;i++){
scanf("%d",&opt);
if(opt==){
scanf("%d%d",&x,&y);
if(find(x)==find(y)){printf("-1\n");continue;}
join(x,y);
}
else if(opt==){
scanf("%d%d",&x,&y);
if(find(x)!=find(y)||x==y){printf("-1\n");continue;}
cut(x,y);
}
else if(opt==){
scanf("%d%d%d",&w,&x,&y);
if(find(x)!=find(y)){printf("-1\n");continue;}
makeroot(x);access(y);splay(y);
val[y]+=w;tag[y]+=w;mx[y]+=w;
}
else {
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");
}
int main(){
while(scanf("%d",&n)!=EOF){
memset(fa,,sizeof(fa));
memset(son,,sizeof(son));
memset(val,,sizeof(val));
memset(mx,,sizeof(mx));
memset(tag,,sizeof(tag));
memset(rev,,sizeof(rev));
work();
}
return ;
}
Query on The Trees(hdu 4010)的更多相关文章
- 动态树(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 ...
- HDOJ 4010 Query on The Trees LCT
LCT: 分割.合并子树,路径上全部点的点权添加一个值,查询路径上点权的最大值 Query on The Trees Time Limit: 10000/5000 MS (Java/Others) ...
- C - Visible Trees HDU - 2841 -莫比乌斯函数-容斥
C - Visible Trees HDU - 2841 思路 :被挡住的那些点(x , y)肯定是 x 与 y不互质.能够由其他坐标的倍数表示,所以就转化成了求那些点 x,y互质 也就是在 1 - ...
- Disharmony Trees HDU - 3015
Disharmony Trees HDU - 3015 One day Sophia finds a very big square. There are n trees in the square. ...
- HDU4010 Query on The Trees (LCT动态树)
Query on The Trees Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Othe ...
- S - Query on a tree HDU - 3804 线段树+dfs序
S - Query on a tree HDU - 3804 离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...
- 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(动态树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4010 题意:一棵树,四种操作: (1)若x和y不在一棵树上,将x和y连边: (2)若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 ...
随机推荐
- 如何在腾讯云上安装Cloud Foundry
Cloud Foundry是VMware推出的业界第一个开源PaaS云平台,它支持多种框架.语言.运行时环境.云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的 ...
- ActiveMQ消息丢失怎么解决?
在消息发送过程中消息丢失的话该怎么解决(包括网络原因): 解决思路: 可以把消息唯一ID,存到表里面,当消息接受端可以获取到这个ID,就给服务端一个回复IF,消息发送出去,没有回复,THEN一直循环发 ...
- UESTC cdoj 619 吴神,人类的希望 (组合数学)
枚举盒子的个数,先把总数n减去掉box*k保证每个盒子至少有k个小球,剩下的小球放入盒子中可以为空, 加入box个小球保证每个盒子至少有一个小球,问题转化成不可区分小球放入不可区分盒子非空的方案数. ...
- windows/Linux 常用命令
windows 文件操作命令 cd 切换文件目录 dir 显示文件目录内容 md 创建文件夹 rd 删除文件夹 copy 拷贝文件 move 移动文件 del 删除文件 replace 替换文件 mk ...
- tomcat假死现象 - 二
1 编写背景 最近服务器发现tomcat的应用会偶尔出现无法访问的情况.经过一段时间的观察最近又发现有台tomcat的应用出现了无法访问情况.简单描述下该台tomcat当时具体的表现:客户端请求没有响 ...
- 歌乐第二弹:C++九九八十一
第一弹传送门:极乐净土 二话不说,上代码(注意事项在第一弹里): #include <windows.h> //q前缀为低音,g为高音,s前缀为半音阶 const int q1 = 131 ...
- 更改ubuntu的官方镜像源
我们自己安装的ubuntu通常默认镜像源是官方的,并不好用,因为网速以及限制比较多,所以为了使用方便,通常都会去更改一下默认的镜像源配置. 这里我们使用清华大学开源镜像软件站,https://mirr ...
- windows显示文件扩展名
搜索打开windows的文件资源管理选项,如下去掉“隐藏已知文件类型的扩展名”即可 打开之后显示如下:
- Linux菜鸟起飞之路【四】绝对路径、相对路径及常用目录
一.绝对路径与相对路径 Linux操作系统中存在着两种路径:绝对路径和相对路径.我们在访问文件或文件夹的时候,其实都是通过路径来操作的.两种路径在实际操作中能起到同等的作用. 在开始具体介绍之前,我们 ...
- 异步FIFO最小深度计算
计算FIFO深度是设计FIFO中常遇到的问题.常识告诉我们,当读速率慢于写速率时,FIFO便可被用作系统中的缓冲元件或队列.因此FIFO的大小基本上暗示了所需缓存数据的容量,该容量取决于读写数据的速率 ...