• 3282: Tree(LCT)


    3282: Tree

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

    code

      1 #include<cstdio>
      2 #include<algorithm>
      3  
      4 using namespace std;
      5  
      6 const int N = 300100;
      7  
      8 int val[N],fa[N],ch[N][2],rev[N],sum[N],st[N],top;
      9  
     10 inline char nc() {
     11     static char buf[100000],*p1 = buf,*p2 = buf;
     12     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF :*p1++;
     13 }
     14 inline int read() {
     15     int x = 0,f = 1;char ch=nc();
     16     for (; ch<'0'||ch>'9'; ch = nc()) if (ch == '-') f = -1;
     17     for (; ch>='0'&&ch<='9'; ch = nc()) x = x*10+ch-'0';
     18     return x * f;
     19 }
     20 void pushup(int x) {
     21     sum[x] = sum[ch[x][1]] ^ sum[ch[x][0]] ^ val[x];
     22 }
     23 void pushdown(int x) {
     24     int l = ch[x][0],r = ch[x][1];
     25     if (rev[x]) {
     26         rev[l] ^= 1;rev[r] ^= 1;
     27         swap(ch[x][0],ch[x][1]);
     28         rev[x] ^= 1;
     29     }
     30 }
     31 bool isroot(int x) {
     32     return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
     33 }
     34 int son(int x) {
     35     return ch[fa[x]][1]==x;
     36 }
     37 void rotate(int x) {
     38     int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
     39     if (!isroot(y)) ch[z][c] = x;fa[x] = z;
     40     ch[x][!b] = y;fa[y] = x;
     41     ch[y][b] = a;if (a) fa[a] = y;
     42     pushup(y);pushup(x);
     43 }
     44 void splay(int x) {
     45     top = 0;st[++top] = x;
     46     for (int i=x; !isroot(i); i=fa[i]) st[++top] = fa[i];
     47     while (top) pushdown(st[top--]);
     48     while (!isroot(x)) {
     49         int y = fa[x];
     50         if (!isroot(y)) {
     51             if (son(x)==son(y)) rotate(y);
     52             else rotate(x);
     53         }
     54         rotate(x);
     55     }
     56 }
     57 void access(int x) {
     58     for (int t=0; x; t=x,x=fa[x]) {
     59         splay(x);ch[x][1] = t;pushup(x);
     60     }
     61 }
     62 void makeroot(int x) {
     63     access(x);
     64     splay(x);
     65     rev[x] ^= 1;
     66 }
     67 void link(int x,int y) {
     68     makeroot(x);
     69     fa[x] = y;
     70 }
     71 void cut(int x,int y) {
     72     makeroot(x);access(y);splay(y);
     73     ch[y][0] = fa[ch[y][0]] = 0;
     74 }
     75 void update(int x,int y) {
     76     makeroot(x);val[x] = y;pushup(x);
     77 }
     78 int query(int x,int y) {
     79     makeroot(x);access(y);splay(y);
     80     return sum[y];
     81 }
     82 int find(int x) {
     83     access(x);splay(x);
     84     while (ch[x][0]) x = ch[x][0];
     85     return x;
     86 }
     87 int main() {
     88     int n = read(),m = read(),opt,x,y;
     89     for (int i=1; i<=n; ++i) sum[i] = val[i] = read();
     90     while (m--) {
     91         opt = read(),x = read(),y = read();
     92         if (opt==0) printf("%d
    ",query(x,y));
     93         else if (opt==1) {
     94             if (find(x)!=find(y)) link(x,y);
     95         }
     96         else if (opt==2) {
     97             if (find(x)==find(y)) cut(x,y);
     98         }
     99         else update(x,y);
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    vue双向数据绑定原理解析及js代码实现
    react 实现tab切换
    vue不是内部或外部命令,解决办法
    JavaScript 基础知识 表达式和运算符
    JavaScript 基础知识 变量与数据类型
    Animation动画-小动画
    Ajax的封装
    esp32 python上位机(命令行)
    ESP32扫描环境中的所有WiFi并且通过串口选择需要连接的WiFi
    Linux修改开机图形/etc/motd
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8150445.html
Copyright © 2020-2023  润新知