BZOJ 3282: Tree [LCT]
Posted Candy?
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3282: Tree [LCT]相关的知识,希望对你有一定的参考价值。
3282: Tree
Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1677 Solved: 744
[Submit][Status][Discuss]
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
1
2
3
1 1 2
0 1 2
0 1 1
Sample Output
3
1
1
HINT
1<=N,M<=300000
Source
不能再做水题了!!!
跟上道题一模一样,只是xor和而已,xor满足结合律
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; #define pa t[x].fa #define lc t[x].ch[0] #define rc t[x].ch[1] const int N=3e5+5; inline int read(){ char c=getchar();int x=0,f=1; while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} return x*f; } struct node{ int ch[2],fa,rev; int sum,w; }t[N]; inline void update(int x){t[x].sum=t[lc].sum^t[rc].sum^t[x].w;} inline int wh(int x){return t[pa].ch[1]==x;} inline int isRoot(int x){return t[pa].ch[0]!=x&&t[pa].ch[1]!=x;} inline void pushDown(int x){ if(t[x].rev){ t[lc].rev^=1; t[rc].rev^=1; swap(lc,rc); t[x].rev=0; } } inline void rotate(int x){ int f=t[x].fa,g=t[f].fa,c=wh(x); if(!isRoot(f)) t[g].ch[wh(f)]=x;t[x].fa=g; t[f].ch[c]=t[x].ch[c^1];t[t[f].ch[c]].fa=f; t[x].ch[c^1]=f;t[f].fa=x; update(f);update(x); } int st[N],top; inline void splay(int x){ top=0;st[++top]=x; for(int i=x;!isRoot(i);i=t[i].fa) st[++top]=t[i].fa; for(int i=top;i>=1;i--) pushDown(st[i]); for(;!isRoot(x);rotate(x)) if(!isRoot(pa)) rotate(wh(x)==wh(pa)?pa:x); } inline void Access(int x){ for(int y=0;x;y=x,x=pa){ splay(x); rc=y; update(x); } } inline void MakeRoot(int x){ Access(x);splay(x); t[x].rev^=1; } inline int FindRoot(int x){ Access(x);splay(x); while(lc) x=lc; return x; } inline void Link(int x,int y){ MakeRoot(x); t[x].fa=y; } inline void Cut(int x,int y){ MakeRoot(x); Access(y);splay(y); t[y].ch[0]=t[x].fa=0; } int n,Q,op,x,y; int main(){ //freopen("in.txt","r",stdin); n=read();Q=read(); for(int i=1;i<=n;i++) t[i].w=t[i].sum=read(); while(Q--){ op=read();x=read();y=read(); if(op==0) MakeRoot(x),Access(y),splay(y),printf("%d\n",t[y].sum); if(op==1) if(FindRoot(x)!=FindRoot(y)) Link(x,y); if(op==2) if(FindRoot(x)==FindRoot(y)) Cut(x,y); if(op==3) t[x].w=y,splay(x); } }
以上是关于BZOJ 3282: Tree [LCT]的主要内容,如果未能解决你的问题,请参考以下文章