代码

#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
const int INF=1e9+;
const int maxn=;
int val[maxn];
int N,Q;
vector<int> G[maxn];
struct lct
{
lct *fa,*son[];
int rev,v,mv,add;
};
struct LCT
{
lct data[maxn];
lct *null;
void init(int Size=maxn-) //初始化
{
null=data; //null指向首元素
for(int i=;i<=Size;i++)
{
data[i].son[]=data[i].son[]=data[i].fa=null;
data[i].v=data[i].mv=val[i];
data[i].rev=data[i].add=;
}
null->v=null->mv=-INF;
}
void dfs(int u,int fa)
{
data[u].fa=data+fa;
int Size=G[u].size();
for(int i=;i<Size;i++)
{
int v=G[u][i];
if(v==fa) continue;
dfs(v,u);
}
}
void push_add(lct* x,int add)
{
if(x==null) return;
x->v+=add;
x->add+=add;
x->mv+=add;
}
void push_rev(lct* x)
{
if(x==null) return;
x->rev=!x->rev;
swap(x->son[],x->son[]);
}
void pushdown(lct* x)
{
if(x->add!=)
{
push_add(x->son[],x->add);
push_add(x->son[],x->add);
x->add=;
}
if(x->rev)
{
push_rev(x->son[]);
push_rev(x->son[]);
x->rev=;
}
}
void pushup(lct* x)
{
if(x==null) return;
x->mv=x->v;
x->mv=max(x->mv,x->son[]->mv);
x->mv=max(x->mv,x->son[]->mv);
}
bool Same(lct* x,lct* &y) //判断x和x的父亲是否在同一树里
{
return (y=x->fa)!=null&&(y->son[]==x||y->son[]==x);
}
void Rotate(lct* x,int d) //翻转
{
lct* y=x->fa; //x的父亲
y->son[d^]=x->son[d];
if(x->son[d]!=null) x->son[d]->fa=y; //x的子节点的父亲指向y
x->fa=y->fa; //连接
if(y->fa->son[]==y) x->fa->son[]=x;
else if(y->fa->son[]==y) x->fa->son[]=x;
x->son[d]=y;
y->fa=x;
}
void Splay(lct* x)
{
pushdown(x); //清除标记
lct* y;
while(Same(x,y)) //没有到树的最顶点
{
pushdown(y);
pushdown(x);
Rotate(x,y->son[]==x); //翻转
pushup(y);
pushup(x);
}
}
lct* Access(lct* u) //打通路径,返回的是根
{
lct *v=null;
for(;u!=null;u=u->fa)
{
Splay(u);
u->son[]=v;
pushup(v=u);
}
return v;
}
lct* GetRoot(lct* x) //得到根
{
for(x=Access(x);pushdown(x),x->son[]!=null;x=x->son[]) pushup(x);
return x;
}
void MakeRoot(lct* x) //使x成为根
{
Access(x);
Splay(x);
push_rev(x);
}
void Link(lct* x,lct* y) //连接两个点
{
MakeRoot(x);
x->fa=y;
Access(x);
}
void Cut(lct* x,lct* y) //断开两个点
{
MakeRoot(x);
Access(y);
Splay(y);
y->son[]->fa=null;
y->son[]=null;
}
void Add(lct* x,lct* y,int add)
{
MakeRoot(x);
push_add(Access(y),add);
}
int MaxVal(lct* x,lct* y)
{
MakeRoot(x);
Access(y);
Splay(y);
return y->mv;
}
}A;
int main()
{
while(scanf("%d",&N)!=EOF)
{
for(int i=;i<=N;i++) G[i].clear();
int x,y;
for(int i=;i<N;i++)
{
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
val[]=;
for(int i=;i<=N;i++) scanf("%d",&val[i]);
A.init(N);
A.dfs(,);
int type,w;
scanf("%d",&Q);
while(Q--)
{
scanf("%d",&type);
if(type==) scanf("%d",&w);
scanf("%d%d",&x,&y);
bool same=(A.GetRoot(A.data+x)==A.GetRoot(A.data+y));
if(type==)
{
if(same) printf("-1\n");
else A.Link(A.data+x,A.data+y);
}
else if(type==)
{
if(x==y||!same) printf("-1\n");
else A.Cut(A.data+x,A.data+y);
}
else if(type==)
{
if(!same) printf("-1\n");
else A.Add(A.data+x,A.data+y,w);
}
else
{
if(!same) printf("-1\n");
else printf("%d\n",A.MaxVal(A.data+x,A.data+y));
}
}
printf("\n");
}
return ;
}

hdu4010-Query on The Trees(lct分裂合并加值查询最大值)的更多相关文章

  1. HDU4010 Query on The Trees(LCT)

    人生的第一道动态树,为了弄懂它的大致原理,需要具备一些前置技能,如Splay树,树链剖分的一些概念.在这里写下一些看各种论文时候的心得,下面的代码是拷贝的CLJ的模板,别人写的模板比较可靠也方便自己学 ...

  2. HDU4010 Query on The Trees (LCT动态树)

    Query on The Trees Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Othe ...

  3. HDOJ 4010 Query on The Trees LCT

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

  4. hdu4010 Query On The Trees

    Problem Description We have met so many problems on the tree, so today we will have a query problem ...

  5. hdu 4010 Query on The Trees LCT

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

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

  7. [BZOJ4530][Bjoi2014]大融合 LCT + 启发式合并

    [BZOJ4530][Bjoi2014]大融合 试题描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是 ...

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

  9. 【bzoj3091】城市旅行 LCT区间合并

    题目描述 输入 输出 样例输入 4 5 1 3 2 5 1 2 1 3 2 4 4 2 4 1 2 4 2 3 4 3 1 4 1 4 1 4 样例输出 16/3 6/1 题解 LCT区间合并 前三个 ...

随机推荐

  1. git 查看文件修改记录

    今天追了个几年前留下来的坑, 在 git 里追溯修改过程坑死个爹, 具体方法估计没多久又会忘, 还是记下来以后有的参考 大部分教程都会告诉大家使用 git log 来查看对应文件的修改记录, 就像这样 ...

  2. 马士兵Servlet&Jsp学习

    Servlet&JSP 1>http常见错误信息:  404--url地址找不找,  403--禁止访问  500--服务器内部错误  2>Servlet的生命周期:  *生命全过 ...

  3. PHP设计模式笔记五:策略模式 -- Rango韩老师 http://www.imooc.com/learn/236

    策略模式 1.概述:策略模式,将一组特定的行为和算法封装成类,以适应某些特定的上下文环境,这种模式称为策略模式 例如:一个电商网站系统,针对男性女性用户要各自跳转到不同的商品类目,并且所有广告位展示不 ...

  4. 外观模式之C++实现

    说明:本文仅供学习交流,转载请标明出处.欢迎转载. 在我们学习程序设计时经常会用到模块化设计的思想,这一思想是我们首先把要实现的功能用一个模块表示,当用户想完毕某个人物时依次调用相应的函数. 然而.假 ...

  5. [置顶] 强制访问控制内核模块Smack

    Smack(Simplified Mandatory Access Control Kernel)是Casey Schaufler[15]于2007年在LSM基础上实现的Linux强制访问控制安全模块 ...

  6. IOS-沙盒机制(一 简述)

    一 IOS沙盒机制       出于安全的目的,应用程序仅仅能将自己的数据和偏好设置写入到几个特定的位置上.当应用程序被安装到设备上时,系统会为其创建一个家文件夹,这个家文件夹就是应用程序的沙盒.所以 ...

  7. C-二维数组,多维数组

    -----二维数组      ->在数组定义当中,行数和列数需要用常量定义      ->在定义的时候如果没有数值进行填充,则补零      ->第一个数是行,第二个数是列     ...

  8. 普通用户登录PLSQL后提示空白OK对话框错误

    问题描述: 1.普通域账号登录域成员服务器后,打开PLSQL正常,输入用户名密码登录后提示一个空白的OK对话框,点确定后又返回到输入用户密码界面. 2.在CMD窗口下调用SQLPLUS登录数据库时报如 ...

  9. 传感器仿真平台——UI绘制模块(二)

    这一章讲的是UI绘制模块 该模块的作用是将实验对象绘制出来,它可能是目标.传感器等等,由于事先并不知道会有哪些物体,也无法事先定义好某个对象该怎么画,以我懒人的性格,得了,就抛给用的人吧~喝前摇一摇, ...

  10. javascript 获取滚动条高度+常用js页面宽度与高度(转)

    /******************** *获取窗口滚动条高度 ******************/ function getScrollTop() { var scrollTop=0; if(d ...