hdu 4010 Query on The Trees LCT
支持:
1.添加边 x,y
2.删边 x,y
3.对于路径x,y上的所有节点的值加上w
4.询问路径x,y上的所有节点的最大权值
分析:
裸的lct...
rev忘了清零死循环了两小时。。。
1:就是link操作
2:就是cut操作
3:维护多一个mx域,mx[x]表示在splay中以节点x为根的子树的最大点权,每次修改时,把x置为splay的根,打通y到x的路径,把y splay到根,那么,直接对y节点的lazy标记加上为w即可。
4:同3操作,把x置为splay的根,打通y到x的路径,把y splay到根,那么,y子树所对应的节点就是路径x到y的所有节点。
另外,题目貌似描述有点问题,不光是询问非法输出-1,是指操作如果是非法就输出-1....
#include <set>
#include <map>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull; #define debug puts("here")
#define rep(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define foreach(i,vec) for(unsigned i=0;i<vec.size();i++)
#define pb push_back
#define RD(n) scanf("%d",&n)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
#define All(vec) vec.begin(),vec.end()
#define MP make_pair
#define PII pair<int,int>
#define PQ priority_queue
#define cmax(x,y) x = max(x,y)
#define cmin(x,y) x = min(x,y)
#define Clear(x) memset(x,0,sizeof(x))
/* #pragma comment(linker, "/STACK:1024000000,1024000000") int size = 256 << 20; // 256MB
char *p = (char*)malloc(size) + size;
__asm__("movl %0, %%esp\n" :: "r"(p) ); */ /******** program ********************/ const int MAXN = 3e5+5; // 外挂
char op;
inline void Int(int &x){
while( !isdigit(op=getchar()) );
x = op-'0';
while(isdigit(op=getchar()))
x = x*10+op-'0';
} struct LCT{
int ch[MAXN][2],fa[MAXN];
int lz[MAXN],mx[MAXN],val[MAXN];
bool rev[MAXN];
int sta[MAXN],top; inline void init(){
Clear(ch);
Clear(fa);
Clear(lz);
Clear(rev);
mx[0] = 0;
} inline void modify(int x,int d){ // 单点增加lazy标记
if(!x)return;
lz[x] += d;
mx[x] += d;
val[x] += d;
} inline void clear(int x){
if(!x)return;
if(rev[x]){
if(ch[x][0])rev[ch[x][0]] ^= 1;
if(ch[x][1])rev[ch[x][1]] ^= 1;
swap(ch[x][0],ch[x][1]);
rev[x] = 0;
}
if(lz[x]){
modify(ch[x][0],lz[x]);
modify(ch[x][1],lz[x]);
lz[x] = 0;
}
} inline void update(int x){
if(!x)return;
mx[x] = max( val[x],max(mx[ch[x][0]],mx[ch[x][1]]) );
} inline bool isRoot(int x){
return !x || !( (ch[ fa[x] ][0]==x) || (ch[ fa[x] ][1]==x) );
} inline bool sgn(int x){
return ch[ fa[x] ][1]==x;
}
inline void setc(int y,int d,int x){
ch[y][d] = x;
fa[x] = y;
}
inline void rot(int x){
int y = fa[x] , z = fa[y] , d = sgn(x)^1;
setc(y,d^1,ch[x][d]);
if(isRoot(y)) fa[x] = fa[y];
else setc(z,sgn(y),x);
setc(x,d,y);
update(y);
} inline void splay(int x){
if(!x)return;
top = 0;
sta[++top] = x;
for(int y=x;!isRoot(y);y=fa[y])
sta[++top] = fa[y];
while(top)clear(sta[top--]); while(!isRoot(x)){
if(isRoot(fa[x]))rot(x);
else{
sgn(x)==sgn(fa[x]) ? rot(fa[x]) : rot(x);
rot(x);
}
}
update(x);
} inline int access(int x){
int y = 0;
for(;x;x=fa[y = x]){
splay(x);
ch[x][1] = y;
update(x);
}
return y;
} inline void mRoot(int x){
rev[ access(x) ] ^= 1;
splay(x);
} inline int getRoot(int x){
x = access(x);
while(ch[x][0]){
x = ch[x][0];
clear(x);
}
return x;
} inline bool jud(int x,int y){// ok
return getRoot(x)==getRoot(y);
} inline void link(int x,int y){
if(jud(x,y)){
puts("-1");
return;
}
mRoot(x);
fa[x] = y;
//access(x);
} inline void cut(int x,int y){
if(x==y||!jud(x,y)){
puts("-1");
return;
}
mRoot(x);
access(y);
splay(y);
fa[ ch[y][0] ] = 0;
ch[y][0] = 0;
update(y);
} inline void modify(int x,int y,int c){
if(!jud(x,y)){
puts("-1");
return;
}
mRoot(x);
access(y);
splay(y);
modify(y,c);
clear(y);
} inline int ask(int x,int y){
if(!jud(x,y))
return -1;
mRoot(x);
access(y);
splay(y);
return mx[y];
} }lct; struct Edge{
int y,next;
}edge[MAXN<<1]; int po[MAXN],tol; inline void add(int x,int y){
edge[++tol].y = y;
edge[tol].next = po[x];
po[x] = tol;
} void dfs(int x,int pa){
lct.fa[x] = pa;
for(int i=po[x];i;i=edge[i].next)
if(edge[i].y!=pa)
dfs(edge[i].y,x);
} int main(){ #ifndef ONLINE_JUDGE
freopen("sum.in","r",stdin);
//freopen("sum.out","w",stdout);
#endif int x,y,w,n,m,op;
while(~RD(n)){
lct.init();
Clear(po);
tol = 0; REP(i,2,n){
Int(x);Int(y);
add(x,y);
add(y,x);
} dfs(1,0); rep1(i,n){
RD(lct.val[i]);
lct.mx[i] = lct.val[i];
}
RD(m);
while(m--){
Int(op);
if(op==1){
Int(x);Int(y);
lct.link(x,y);
}else if(op==2){
Int(x);Int(y);
lct.cut(x,y);
}else if(op==3){
Int(w);Int(x);Int(y);
lct.modify(x,y,w);
}else{
Int(x);Int(y);
printf("%d\n",lct.ask(x,y));
}
}
puts("");
} return 0;
}
hdu 4010 Query on The Trees LCT的更多相关文章
- 动态树(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) ...
- 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 (动态树)(Link-Cut-Tree)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4010 题意; 先给你一棵树,有 \(4\) 种操作: 1.如果 \(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 解题报告
题意: 给出一颗树,有4种操作: 1.如果x和y不在同一棵树上则在xy连边 2.如果x和y在同一棵树上并且x!=y则把x换为树根并把y和y的父亲分离 3.如果x和y在同一棵树上则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(动态树)
题意 给定一棵 \(n\) 个节点的树,每个点有点权.完成 \(m\) 个操作,操作四两种,连接 \((x,y)\) :提 \(x\) 为根,并断 \(y\) 与它的父节点:增加路径 \((x,y)\ ...
- HDU4010 Query on The Trees(LCT)
人生的第一道动态树,为了弄懂它的大致原理,需要具备一些前置技能,如Splay树,树链剖分的一些概念.在这里写下一些看各种论文时候的心得,下面的代码是拷贝的CLJ的模板,别人写的模板比较可靠也方便自己学 ...
随机推荐
- Ehcache详细解读
[http://raychase.iteye.com/blog/1545906] Ehcache 是现在最流行的纯Java开源缓存框架. [通过编程方式使用EhCache ] //从class ...
- TCP/IP TIME_WAIT状态原理
原文转载:http://elf8848.iteye.com/blog/1739571 IME_WAIT状态原理 ---------------------------- 通信双方建立TCP连接后,主动 ...
- VCL -- Understanding the Message-Handling System
Understanding the Message-Handling System http://docwiki.embarcadero.com/RADStudio/XE7/en/Understand ...
- C# 如何编辑文件的摘要信息
我的以前的测试报告程序需要在倒完测试数据报告后,在文件摘要中加上一些类似版权说明的文字等等. 因此需要对文件摘要信息进行编辑. 我的记忆中以前好像只有office文档才可以又摘要信息, 现在看来基本上 ...
- C# 图片裁剪代码
/// <summary> /// 缩小裁剪图片 /// </summary> /// <param name="int_Width">要缩小裁 ...
- 都是iconv惹的祸
今天在做采集的时候发现只取到了网页的部分内容,当时我就郁闷了,之前都用的采集都可以采集到网页的所有内容,但这次死活就取到部分内容.寻找原因才知道原来是iconv惹的祸. 发现问题时,网上搜了搜,才发现 ...
- [程序猿入行必备]CSS样式之优先级
专业玩家请移步:http://www.w3.org/TR/CSS2/cascade.html 使用CSS控制页面样式时,常常出现设定的样式被"覆盖",不能生效的情况. 浏览器是根据 ...
- Hello_IOS ios开发transform属性
#import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutl ...
- 三星Galaxy S4(GT-I9500)获取ROOT权限教程(转)
http://news.candou.com/2013-05-20/453695_1.shtml 获取root权限的方法
- LINUX 逻辑地址、线性地址、物理地址和虚拟地址 转
一.概念物理地址(physical address)用于内存芯片级的单元寻址,与处理器和CPU连接的地址总线相对应.——这个概念应该是这几个概念中最好理解的一个,但是值得一提的是,虽然可以直接把物理地 ...