码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 3282: Tree [LCT]

时间:2017-01-12 02:42:35      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:color   return   pac   xor   memory   define   blog   联通   ++   

3282: Tree

Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 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

Sample Output

3
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]

标签:color   return   pac   xor   memory   define   blog   联通   ++   

原文地址:http://www.cnblogs.com/candy99/p/6274184.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!