• Bzoj3282 Tree


    Time Limit: 30 Sec  Memory Limit: 512 MB
    Submit: 1764  Solved: 785

    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裸题

    喜闻乐见1A

    再跟自己说一遍:把x变为树根的时候rev不会影响到右子树是因为x的右子树在access的时候已经断掉了! ←每次写LCT都要在这里犯迷糊也是够了

      1 /*by SilverN*/
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 #include<vector>
      8 using namespace std;
      9 const int mxn=301115;
     10 int read(){
     11     int x=0,f=1;char ch=getchar();
     12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     14     return x*f;
     15 }
     16 struct node{
     17     int ch[2],fa;
     18     int val,smm;
     19     bool rev;
     20 }t[mxn];
     21 inline bool isroot(const int x){return (t[t[x].fa].ch[0]!=x && t[t[x].fa].ch[1]!=x);}
     22 void pushup(int x){
     23     int lc=t[x].ch[0],rc=t[x].ch[1];
     24 //    printf("x:%d lc:%d %d rc:%d %d
    ",x,lc,t[lc].smm,rc,t[rc].smm);
     25     t[x].smm=t[lc].smm^t[rc].smm^t[x].val;
     26     return;
     27 }
     28 void PD(int x){
     29     if(t[x].rev){
     30         t[t[x].ch[0]].rev^=1;
     31         t[t[x].ch[1]].rev^=1;
     32         swap(t[x].ch[0],t[x].ch[1]);
     33         t[x].rev^=1;
     34     }
     35     return;
     36 }
     37 void rotate(int &x){
     38     int y=t[x].fa,z=t[y].fa,lc,rc;
     39     if(t[y].ch[0]==x)lc=0;else lc=1; rc=lc^1;
     40     if(!isroot(y)){t[z].ch[t[z].ch[1]==y]=x;}
     41     t[x].fa=z;t[y].fa=x;
     42     t[y].ch[lc]=t[x].ch[rc];
     43     t[t[x].ch[rc]].fa=y;    
     44     t[x].ch[rc]=y;
     45     pushup(y);
     46     return;
     47 }
     48 int st[mxn],top=0;
     49 void Splay(int &x){
     50     top=0;st[++top]=x;
     51     for(int i=x;!isroot(i);i=t[i].fa){st[++top]=t[i].fa;}
     52     while(top)PD(st[top--]);
     53     while(!isroot(x)){
     54         int y=t[x].fa,z=t[y].fa;
     55         if(!isroot(y)){
     56             if((t[z].ch[0]==y)^(t[y].ch[0]==x))rotate(x);
     57             else rotate(y);
     58         }
     59         rotate(x);
     60     }
     61     pushup(x);
     62     return;
     63 }
     64 void access(int x){
     65     int y=0;
     66     for(;x;x=t[x].fa){
     67         Splay(x);
     68         t[x].ch[1]=y;
     69         pushup(x);
     70         y=x;
     71     }
     72     return;
     73 }
     74 void mkroot(int x){
     75     access(x);Splay(x);
     76     t[x].rev^=1;
     77     return;
     78 }
     79 int find(int x){
     80     access(x);Splay(x);
     81     while(t[x].ch[0])x=t[x].ch[0];
     82     return x;
     83 }
     84 void link(int x,int y){
     85     mkroot(x);
     86     t[x].fa=y;
     87     return;
     88 }
     89 void cut(int x,int y){
     90     mkroot(x);access(y);Splay(y);
     91     if(t[y].ch[0]==x){t[y].ch[0]=0;t[x].fa=0;}
     92     return;
     93 }
     94 int query(int x,int y){
     95     mkroot(x);
     96     access(y);Splay(y);
     97     return t[y].smm;
     98 }
     99 int n,m;
    100 int main(){
    101 //    freopen("in.txt","r",stdin);
    102     int i,j;
    103     n=read();m=read();
    104     for(i=1;i<=n;i++){
    105 //        t[i].fa=i; //Wrong!
    106         t[i].smm=t[i].val=read();
    107     }
    108     int u,v,op;
    109     while(m--){
    110         op=read();u=read();v=read();
    111         switch(op){
    112             case 0:{
    113                 printf("%d
    ",query(u,v));
    114                 break;
    115             }
    116             case 1:{
    117                 if(find(u)!=find(v))link(u,v);
    118                 break;
    119             }
    120             case 2:{
    121                 if(find(u)==find(v))cut(u,v);
    122                 break;
    123             }
    124             case 3:{
    125                 access(u);    Splay(u);
    126                 t[u].val=v;
    127                 pushup(u);
    128                 break;
    129             }
    130         }
    131     }
    132     return 0;
    133 }
  • 相关阅读:
    1046 A^B Mod C
    1019 逆序数
    1012 最小公倍数LCM
    1011 最大公约数GCD
    序列化
    bigdecimal
    equals 和hashcode
    java多线程-读写锁原理
    Java并发编程:volatile关键字解析
    面试
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6550222.html
Copyright © 2020-2023  润新知