zoukankan      html  css  js  c++  java
  • [luogu 3690]Link Cut Tree

    题目背景

    动态树

    题目描述

    给定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。

    输入输出格式

    输入格式:

    第1行两个整数,分别为N和M,代表点数和操作数。

    第2行到第N+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。

    第N+2行到第N+M+1行,每行三个整数,分别代表操作类型和操作所需的量。

    输出格式:

    对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。

    输入输出样例

    输入样例#1: 复制
    3 3 
    1
    2
    3
    1 1 2
    0 1 2 
    0 1 1
    输出样例#1: 复制
    3
    1

    说明

    数据范围: $1 leq N, M leq 3 cdot {10}^5$

    题解:

    动态树练手。

      1 //Never forget why you start
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<cmath>
      7 #include<algorithm>
      8 #define ll(x) lct[x].child[0]
      9 #define rr(x) lct[x].child[1]
     10 #define son(x,t) lct[x].child[t]
     11 using namespace std;
     12 int n,m;
     13 int read(){
     14   int ans=0,f=1;char i=getchar();
     15   while(i<'0'||i>'9'){if(i=='-')f=-1;i=getchar();}
     16   while(i>='0'&&i<='9'){ans=ans*10+i-'0';i=getchar();}
     17   return ans*f;
     18 }
     19 struct LCT{
     20   int child[2],fa,x,size,sum,rev;
     21   bool is_root;
     22 }lct[300005];
     23 void push_up(int root){
     24   if(!root)return;
     25   lct[root].sum=lct[root].x^lct[ll(root)].sum^lct[rr(root)].sum;
     26   lct[root].size=lct[ll(root)].size+lct[rr(root)].size+1;
     27 }
     28 int getson(int x){
     29   return x==son(lct[x].fa,1);
     30 }
     31 void push_rev(int x){
     32   if(!x)return;
     33   swap(ll(x),rr(x));
     34   lct[x].rev^=1;
     35 }
     36 void push_down(int x){
     37   if(lct[x].rev&&x){
     38     push_rev(ll(x));
     39     push_rev(rr(x));
     40     lct[x].rev^=1;
     41   }
     42 }
     43 void push(int x){
     44   if(!lct[x].is_root)push(lct[x].fa);
     45   push_down(x);
     46 }
     47 void rotate(int x){
     48   if(lct[x].is_root)return;
     49   int fa=lct[x].fa,fafa=lct[fa].fa,t=getson(x);
     50   son(fa,t)=son(x,!t);if(son(x,!t))lct[son(x,!t)].fa=fa;
     51   lct[fa].fa=x;son(x,!t)=fa;
     52   lct[x].fa=fafa;
     53   if(!lct[fa].is_root)son(fafa,son(fafa,1)==fa)=x;
     54   else lct[x].is_root=1,lct[fa].is_root=0;
     55   push_up(fa);
     56   push_up(x);
     57 }
     58 void splay(int x){
     59   push(x);
     60   for(int fa;!lct[x].is_root;rotate(x))
     61     if(!lct[fa=lct[x].fa].is_root)
     62       rotate(getson(fa)==getson(x)?fa:x);
     63 }
     64 void access(int x){
     65   int y=0;
     66   while(x){
     67     splay(x);
     68     lct[rr(x)].is_root=1;
     69     lct[rr(x)=y].is_root=0;
     70     push_up(x);
     71     x=lct[y=x].fa;
     72   }
     73 }
     74 void mroot(int x){
     75   access(x);
     76   splay(x);
     77   push_rev(x);
     78 }
     79 void link(int u,int v){
     80   mroot(u);
     81   lct[u].fa=v;
     82 }
     83 void cut(int u,int v){
     84   mroot(u);
     85   access(v);splay(v);
     86   lct[son(v,0)].fa=lct[v].fa;
     87   lct[son(v,0)].is_root=1;
     88   ll(v)=lct[v].fa=0;
     89   push_up(v);
     90 }
     91 int find(int x){
     92   access(x);
     93   splay(x);
     94   if(ll(x))x=ll(x);
     95   return x;
     96 }
     97 int main(){
     98   int i,j;
     99   n=read();m=read();
    100   for(i=1;i<=n;i++){
    101     lct[i].x=lct[i].sum=read();
    102     lct[i].size=1;
    103     ll(i)=rr(i)=lct[i].fa=0;
    104     lct[i].is_root=1;
    105   }
    106   int a,b,c;
    107   for(i=1;i<=m;i++){
    108     c=read();a=read();b=read();
    109     if(c==0){
    110       mroot(a);
    111       access(b);
    112       splay(b);
    113       printf("%d
    ",lct[b].sum);
    114     }
    115     else if(c==1){
    116       int p=find(a),q=find(b);
    117       if(p!=q)link(a,b);
    118     }
    119     else if(c==2){
    120       mroot(a);
    121       access(b);
    122       splay(b);
    123       if(ll(b)==a)cut(a,b);
    124     }
    125     else{
    126       mroot(a);
    127       splay(a);
    128       lct[a].x=b;
    129       push_up(a);
    130     }
    131   }
    132   return 0;
    133 }
  • 相关阅读:
    极客mysql01
    Mysql之存储过程与存储函数
    MySQL视图详细介绍
    mysql 触发器的创建和使用
    分治 315. 计算右侧小于当前元素的个数
    128. 最长连续序列
    MySQL慢查询开启、日志分析(转)
    如何在Linux服务器上安装MariaDB或MySQL?
    如何重设MySQL的root密码
    如何修复docker-machine: command not found error
  • 原文地址:https://www.cnblogs.com/huangdalaofighting/p/8300952.html
Copyright © 2011-2022 走看看