【BZOJ3282】Tree
2016-01-27 20:53
281 查看
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
动态树
今天写了一天水题..
给定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
动态树
今天写了一天水题..
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define MAXN 300010 #define GET (ch>='0'&&ch<='9') using namespace std; int n,q; int sta[MAXN],top; struct splay { int ch[2],fa,sum,val; bool rev; }tree[MAXN]; inline void in(int &x) { char ch=getchar();x=0; while (!GET) ch=getchar(); while (GET) x=x*10+ch-'0',ch=getchar(); } inline bool is_root(int x) { return tree[tree[x].fa].ch[0]!=x&&tree[tree[x].fa].ch[1]!=x; } inline void push_up(int x) { tree[x].sum=tree[tree[x].ch[0]].sum^tree[tree[x].ch[1]].sum^tree[x].val; } inline void push_down(int x) { if (tree[x].rev) { tree[tree[x].ch[0]].rev^=1;tree[tree[x].ch[1]].rev^=1; swap(tree[x].ch[0],tree[x].ch[1]);tree[x].rev^=1; } } inline void rot(int x) { int y=tree[x].fa,z=tree[y].fa,l,r; l=(tree[y].ch[1]==x);r=l^1; if (!is_root(y)) tree[z].ch[tree[z].ch[1]==y]=x; tree[x].fa=z;tree[tree[x].ch[r]].fa=y;tree[y].fa=x; tree[y].ch[l]=tree[x].ch[r];tree[x].ch[r]=y; push_up(y);push_up(x); } inline void Splay(int x) { sta[++top]=x; for (int i=x;!is_root(i);i=tree[i].fa) sta[++top]=tree[i].fa; while (top) push_down(sta[top--]); while (!is_root(x)) { int y=tree[x].fa,z=tree[y].fa; if (!is_root(y)) { if ((tree[y].ch[0]==x)^(tree[z].ch[0]==y)) rot(x); else rot(y); } rot(x); } } inline void access(int x) { for (int i=0;x;i=x,x=tree[x].fa) Splay(x),tree[x].ch[1]=i,push_up(x); } inline void make_root(int x) { access(x);Splay(x);tree[x].rev^=1; } inline int find(int x) { for (access(x),Splay(x);tree[x].ch[0];x=tree[x].ch[0]); return x; } inline void link(int x,int y) { if (find(x)==find(y)) return; make_root(x);tree[x].fa=y; } inline void cut(int x,int y) { if (find(x)!=find(y)) return; make_root(x);access(y);Splay(y);tree[y].ch[0]=tree[x].fa=0;push_up(y); } inline void split(int x,int y) { make_root(x);access(y);Splay(y); } int main() { in(n);in(q);int opt,u,v; for (int i=1;i<=n;i++) in(tree[i].val),tree[i].sum=tree[i].val; while (q--) { in(opt);in(u);in(v); if (opt==0) split(u,v),printf("%d\n",tree[v].sum); if (opt==1) link(u,v); if (opt==2) cut(u,v); if (opt==3) access(u),Splay(u),tree[u].val=v,push_up(u); } }
相关文章推荐
- [BZOJ2594][WC2006][LCT][MST]水管局长数据加强版
- 【LCT】BZOJ2049[Sdoi2008]Cave 洞穴勘测
- SPOJ QTREE LCT
- BZOJ1180 [CROATIAN2009]OTOCI
- bzoj2049: [Sdoi2008]Cave 洞穴勘测
- bzoj-2001 City 城市建设
- bzoj-2555 SubString
- bzoj-1180 OTOCI
- Aizu 2450 Do use segment tree LCT
- 【NOI2014】【BZOJ3669】魔法森林
- 【WC2006】【BZOJ2594】水管局长数据加强版
- 【BZOJ4025】二分图
- 【SDOI2014】【BZOJ3531】旅行
- 【WC2005】【BZOJ1453】Dface双面棋盘
- 论在LCT上下放标记
- BZOJ 2001 Hnoi2010 城市建设 分治+LCT
- LCT(Link Cut Tree)学习小记
- BZOJ 4202: 石子游戏 SG定理+LCT
- [BZOJ2959]长跑(LCT)
- [BZOJ2555]SubString(后缀自动机+LCT)