BZOJ 3282: Tree (LCT)题解
来源:互联网 发布:vb 打开文件管理器 编辑:程序博客网 时间:2024/06/06 16:39
Time Limit: 30 Sec Memory Limit: 512 MB
Submit: 2119 Solved: 973
Description
给定N个点以及每个点的权值,要你处理接下来的M个操作。操作有4种。操作从0到3编号。点从1到N编号。
0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。
1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。
2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。
3:后接两个整数(x,y),代表将点X上的权值变成Y。
Input
第1行两个整数,分别为N和M,代表点数和操作数。
第2行到第N+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。
第N+2行到第N+M+1行,每行三个整数,分别代表操作类型和操作所需的量。
Output
对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。
Sample Input
3 3
1
2
3
1 1 2
0 1 2
0 1 1
Sample Output
3
1
HINT
1<=N,M<=300000
Source
动态树
裸LCT,如果不会LCT的朋友可以以这道题为LCT第一题,因为非常的裸,还可以看我的LCT讲解
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>const int MAXN=300010;using namespace std;struct Tree{ int child[2],sum,val,fa,rev;}tree[MAXN];int n,Q,opt,xx,yy;void pushup(int x){tree[x].sum=tree[tree[x].child[0]].sum^tree[tree[x].child[1]].sum^tree[x].val;}void pushdown(int x){ if(tree[x].rev){ tree[x].rev^=1; tree[tree[x].child[0]].rev^=1; tree[tree[x].child[1]].rev^=1; swap(tree[x].child[0],tree[x].child[1]); }}bool isroot(int x){ return (tree[tree[x].fa].child[0]!=x)&&(tree[tree[x].fa].child[1]!=x);}void Pushdown(int x){ if(!isroot(x)) Pushdown(tree[x].fa); pushdown(x);}void rotate(int x){ int y=tree[x].fa,z=tree[y].fa,l,r; if(tree[y].child[0]==x) l=0;else l=1;r=l^1; if(!isroot(y)){ if(tree[z].child[0]==y)tree[z].child[0]=x; else tree[z].child[1]=x; } tree[x].fa=z;tree[y].fa=x;tree[tree[x].child[r]].fa=y; tree[y].child[l]=tree[x].child[r];tree[x].child[r]=y; pushup(y);pushup(x);}void splay(int x){ Pushdown(x); while(!isroot(x)){ int y=tree[x].fa,z=tree[y].fa; if(!isroot(y)){ if((tree[y].child[0]==x)^(tree[z].child[0]==y)) rotate(x); else rotate(y); } rotate(x); }}void access(int x){for(register int i=0;x;i=x,x=tree[x].fa){splay(x);tree[x].child[1]=i;pushup(x);}}void reverse(int x){access(x);splay(x);tree[x].rev^=1;}int findroot(int x){access(x);splay(x);while(tree[x].child[0])x=tree[x].child[0];return x;}void link(int x,int y){reverse(x);tree[x].fa=y;}void cnt(int x,int y){reverse(x);access(y);splay(y);if(tree[y].child[0]==x) tree[y].child[0]=tree[x].fa=0;}int main(){ scanf("%d%d",&n,&Q); for(register int i=1;i<=n;i++)scanf("%d",&tree[i].val),tree[i].sum=tree[i].val; while(Q--){ scanf("%d%d%d",&opt,&xx,&yy); switch(opt){ case 0:reverse(xx);access(yy);splay(yy); printf("%d\n",tree[yy].sum);break; case 1:if(findroot(xx)!=findroot(yy)) link(xx,yy);break; case 2:if(findroot(xx)==findroot(yy)) cnt(xx,yy);break; case 3:access(xx);splay(xx);tree[xx].val=yy;pushup(xx);break; } } return 0;}
阅读全文
1 0
- BZOJ 3282: Tree (LCT)题解
- 【BZOJ】【P2631】【tree】【题解】【LCT】
- 【BZOJ 3282】Tree LCT
- [BZOJ]3282: Tree lct
- BZOJ 3282 Tree Link-Cut-Tree(LCT)
- BZOJ 1180: [CROATIAN2009]OTOCI (LCT题解)
- bzoj 3282 Tree 动态树LCT
- bzoj 3282: Tree LCT第三题
- bzoj 2002 link cut tree(LCT)
- BZOJ 2631 tree LCT
- 【LCT】BZOJ 2631:tree
- BZOJ 2631 Tree LCT
- BZOJ 2631 tree LCT
- 【BZOJ 2631】tree LCT
- BZOJ 2631: tree LCT
- bzoj 2631: tree LCT
- BZOJ 1036: [ZJOI2008]树的统计Count (LCT题解)
- BZOJ 2631 Tree Link-Cut-Tree(LCT)
- pycharm执行python文件无法生成测试报告(appium自动化测试)
- 金额大小写转化、阿拉伯数字转大写数字,大写数字转阿拉伯数字
- 如何才能做好引链?
- 1013. 数素数 (20)
- SDP协议分析
- BZOJ 3282: Tree (LCT)题解
- 属性动画
- Source Tree 总是弹出登录bitbucket账号的对话框
- 数据库中第一范式、第二范式、第三范式
- Log4j配置
- JAVA机试编程—字符串
- Join与CountDownLatch
- java中反射的作用有哪些?
- android apk 防止反编译技术第三篇-加密