[hdu4010]: Query on The Trees

  大概是有史以来调LCT调得最惨的一次了。。因为删边那里判断是否合法时少了个条件。。调了整个晚上>_<。。。。

  被模版题教做人了QAQ。。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 using namespace std;
  5 const int maxn=300233;
  6 struct zs{
  7     int too,pre;
  8 }e[maxn<<1];int tot,last[maxn],dl[maxn];
  9 int ch[maxn][2],fa[maxn],mxv[maxn],v[maxn],add[maxn],st[maxn],top;
 10 bool rev[maxn];
 11 int i,j,k,n,m,x,y,w;
 12
 13 int ra;char rx;
 14 inline int read(){
 15     rx=getchar(),ra=0;
 16     while(rx<‘0‘||rx>‘9‘)rx=getchar();
 17     while(rx>=‘0‘&&rx<=‘9‘)ra*=10,ra+=rx-48,rx=getchar();return ra;
 18 }
 19
 20 inline void insert(int a,int b){
 21     e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;
 22     e[++tot].too=a,e[tot].pre=last[b],last[b]=tot;
 23 }
 24
 25 inline int max(int a,int b){return a>b?a:b;}
 26 inline bool isrt(int x){
 27     return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
 28 }
 29 inline void pushdown(int x){
 30     int l=ch[x][0],r=ch[x][1];
 31     if(rev[x]){
 32         swap(ch[x][0],ch[x][1]),
 33         rev[l]^=1,rev[r]^=1,rev[x]=0;
 34     }
 35     if(add[x]){
 36         if(l)add[l]+=add[x],mxv[l]+=add[x],v[l]+=add[x];
 37         if(r)add[r]+=add[x],mxv[r]+=add[x],v[r]+=add[x];
 38         add[x]=0;
 39     }
 40 }
 41 inline void upd(int x){
 42     mxv[x]=max(mxv[ch[x][0]],mxv[ch[x][1]]);
 43     if(mxv[x]<v[x])mxv[x]=v[x];
 44 }
 45 inline void rotate(int x){
 46     int f=fa[x],gfa=fa[f],l=ch[f][1]==x,r=l^1;
 47     if(!isrt(f))ch[gfa][ch[gfa][1]==f]=x;
 48     fa[ch[f][l]=ch[x][r]]=f,fa[fa[ch[x][r]=f]=x]=gfa,
 49     upd(f);
 50 }
 51 inline void splay(int x){
 52     int f=x,gfa;
 53     for(st[top=1]=f;!isrt(f);)st[++top]=(f=fa[f]);
 54     while(top)pushdown(st[top--]);
 55     while(!isrt(x)){
 56         f=fa[x],gfa=fa[f];
 57         if(!isrt(f))
 58             rotate(((ch[f][1]==x)^(ch[gfa][1]==f))?x:f);
 59         rotate(x);
 60     }
 61     upd(x);
 62 }
 63 inline void access(int x){
 64     for(int rc=0;x;rc=x,x=fa[x])
 65         splay(x),ch[x][1]=rc,upd(x);
 66 }
 67 inline void makert(int x){
 68     access(x),splay(x),rev[x]^=1;
 69 }
 70 inline void link(int x,int y){
 71     makert(x),fa[x]=y;
 72 }
 73 inline void cut(int x,int y){
 74     makert(x),access(y),splay(y),fa[ch[y][0]]=0,ch[y][0]=0,upd(y);
 75 }
 76 inline int getfa(int x){
 77     for(access(x),splay(x);ch[x][0];x=ch[x][0]);
 78     return x;
 79 }
 80
 81 int main(){
 82     mxv[0]=-200023333;bool first=1;
 83     while(scanf("%d",&n)==1){
 84         if(!first)
 85             for(i=0;i<=n;i++)rev[i]=add[i]=ch[i][0]=ch[i][1]=last[i]=0;
 86         else first=0;
 87         tot=0;
 88
 89         for(i=1;i<n;i++)
 90             x=read(),y=read(),insert(x,y);
 91         for(i=1;i<=n;i++)v[i]=mxv[i]=read();
 92         int l=0,r=1,now;dl[1]=1;fa[1]=0;
 93
 94         while(l<r){
 95             now=dl[++l];
 96             for(i=last[now];i;i=e[i].pre)if(e[i].too!=fa[now])
 97                 fa[dl[++r]=e[i].too]=now;
 98         }
 99
100         m=read();char id;
101         while(m--){
102             for(id=getchar();id<‘0‘||id>‘9‘;id=getchar());
103             if(id==‘3‘)w=read();
104             x=read(),y=read();bool sm=(getfa(x)==getfa(y));
105             if(id==‘1‘)
106                 if(sm)puts("-1");
107                 else link(x,y);
108             if(id==‘2‘)
109                 if(!sm||x==y)puts("-1");
110                 else cut(x,y);
111             if(id==‘3‘)
112                 if(!sm)puts("-1");
113                 else makert(x),access(y),splay(y),add[y]+=w,mxv[y]+=w,v[y]+=w;
114             if(id==‘4‘)
115                 if(!sm)puts("-1");
116                 else makert(x),access(y),splay(y),printf("%d\n",mxv[y]);
117         }
118         puts("");
119     }
120     return 0;
121 }

时间: 2024-12-30 00:50:13

[hdu4010]: Query on The Trees的相关文章

HDU4010 Query on The Trees(LCT)

人生的第一道动态树,为了弄懂它的大致原理,需要具备一些前置技能,如Splay树,树链剖分的一些概念.在这里写下一些看各种论文时候的心得,下面的代码是拷贝的CLJ的模板,别人写的模板比较可靠也方便自己学习理解,然后一些概念的则是学习了一些论文,下面的内容可以看作对别人模板的理解心得,以及对论文的收获体会. LCT支持的主要是一种树路径上的操作,譬如说对u和v之间的路径上询问点权的和,询问点权的最大值,对所有点权加一个数,置为一个树等等.它和树链剖分不同的是,它支持将这个树上的边切掉,也支持将两个树

HDOJ 4010 Query on The Trees LCT

LCT: 分割.合并子树,路径上全部点的点权添加一个值,查询路径上点权的最大值 Query on The Trees Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 2582    Accepted Submission(s): 1208 Problem Description We have met so many problems

HDOJ 题目4010 Query on The Trees(Link Cut Tree连接,删边,路径点权加,路径点权最大值)

Query on The Trees Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 3602    Accepted Submission(s): 1587 Problem Description We have met so many problems on the tree, so today we will have a qu

【HDU4010】【LCT】Query on The Trees

Problem Description 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 ef

hdu 4010 Query on The Trees(动态树)

题意:给定一幅图的连接情况,给出每个点的权值,四种操作: 1 x y 连接x.y所在子树: 2 x y 将同一棵树上的x,y分离,形成两棵子树: 3 w x y 将x.y之间路径上的所有点权加w: 4 x y 查询x.y路径上点权的最大值: 动态树学习参考:http://www.cnblogs.com/BLADEVIL/p/3510997.html http://wenku.baidu.com/view/75906f160b4e767f5acfcedb http://m.blog.csdn.ne

HDU 4010.Query on The Trees 解题报告

题意: 给出一颗树,有4种操作: 1.如果x和y不在同一棵树上则在xy连边 2.如果x和y在同一棵树上并且x!=y则把x换为树根并把y和y的父亲分离 3.如果x和y在同一棵树上则x到y的路径上所有的点权值+w 4.如果x和y在同一棵树上则输出x到y路径上的最大值 动态树入门题: #include <iostream> #include <cstdio> using namespace std; const int MAXN = 333333; struct node { int v

HDU 4010 Query on The Trees

题意: 一棵树  支持合并.分离.路径加权值.路径权值最大值 思路: LCT入门题  也是我的第一道-  代码来源于kuangbin巨巨  我只是整理出自己的风格留作模版- LCT比较好的入门资料是--<QTREE解法的一些研究> LCT基本做法就是先dfs建树  然后根据输入做上述4个操作 对于合并  就是把u转到树根  然后接在v上 对于分离  就是把u转到splay的根  然后切断与左子树的连接 对于路径加值  就是求出lca  然后包含u和v的子树以及lca点进行加值 对于路径求最值 

HDU 4010 Query on The Trees (动态树)(Link-Cut-Tree)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4010 题意; 先给你一棵树,有 \(4\) 种操作: 1.如果 \(x\) 和 \(y\) 不在同一棵树上则在\(x-y\)连边. 2.如果 \(x\) 和 \(y\) 在同一棵树上并且 \(x!=y\) 则把 \(x\) 换为树根并把 \(y\) 和 \(y\) 的父亲分离. 3.如果 \(x\) 和 \(y\) 在同一棵树上则 \(x\) 到 \(y\) 的路径上所有的点权值\(+w\). 4

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> #i