• 动态树LCT


    [LuoguP3690]

    跟随ZYP巨佬的步伐学习了一下LCT。

    最大的不同是它有了实边和虚边之分。

    这里推荐一篇学习的博客,[FlashHu 的博客]

    Code:

      1 #include <bits/stdc++.h>
      2 #define ls t[x][0]
      3 #define rs t[x][1]
      4 using namespace std;
      5 const int N = 3e5 + 7;
      6 int read() {
      7     int re = 0, f = 1;
      8     char ch = getchar();
      9     while (ch < '0' || ch > '9') {if (ch == '-') f = -f; ch = getchar();}
     10     while ('0' <= ch && ch <= '9') {re = re * 10 + ch - '0'; ch = getchar();}
     11     return re * f;
     12 }
     13 int n, m;
     14 bool rev[N];
     15 int t[N][2], fa[N], val[N], s[N], stk[N];
     16 bool isroot(int x) {
     17     return t[fa[x]][0] == x || t[fa[x]][1] == x;
     18 }
     19 void pushup(int x) {
     20     s[x] = s[ls] ^ s[rs] ^ val[x];
     21 }
     22 void reverse(int x) {
     23     rev[x] ^= 1;
     24     swap(ls, rs);
     25 }
     26 void pushdown(int x) {
     27     if (rev[x]) {
     28         if (ls) reverse(ls);
     29         if (rs) reverse(rs);
     30         rev[x] = 0;
     31     }
     32 }
     33 int identify(int x) {
     34     return t[fa[x]][1] == x;
     35 }
     36 void connect(int x, int father, int Son) {
     37     fa[x] = father;
     38     t[father][Son] = x;
     39 }
     40 void rotate(int x) {
     41     int y = fa[x], fason = identify(x);
     42     int gfa = fa[y], gfason = identify(y);
     43     int B = t[x][fason ^ 1];
     44     fa[x] = fa[y];
     45     if (isroot(y)) connect(x, gfa, gfason);
     46     connect(B, y, fason), connect(y, x, fason ^ 1);
     47     pushup(y), pushup(x);
     48 }
     49 void splay(int x) {
     50     int y = x, top = 0;
     51     stk[++top] = y;
     52     while (isroot(y)) stk[++top] = fa[y], y = fa[y];
     53     while (top) pushdown(stk[top--]);
     54     while (isroot(x)) {
     55         y = fa[x], top = fa[y];
     56         if (isroot(y)) {
     57             rotate((t[y][0] == x) ^ (t[top][0] == y) ? x : y);
     58         }
     59         rotate(x);
     60     }
     61     pushup(x);
     62 }
     63 void access(int x) { 
     64     for (int y = 0; x; y = x, x = fa[x]) {
     65         splay(x), rs = y, pushup(x);
     66     }
     67 }
     68 void makeroot(int x) {
     69     access(x), splay(x), reverse(x);
     70 }
     71 int findroot(int x) {
     72     access(x), splay(x);
     73     while (ls) pushdown(x), x = ls;
     74     splay(x);
     75     return x;
     76 }
     77 void split(int x, int y) {
     78     makeroot(x);
     79     access(y), splay(y);
     80 }
     81 void link(int x, int y) {
     82     makeroot(x);
     83     if (findroot(y) != x) fa[x] = y;
     84 }
     85 void cut(int x, int y) {
     86     makeroot(x);
     87     if (findroot(y) == x && fa[y] == x && !t[y][0]) {
     88         fa[y] = t[x][1] = 0;
     89         pushup(x);
     90     }
     91 }
     92 int main () {
     93     n = read(), m = read();
     94     for (int i = 1; i <= n; i++) {
     95         val[i] = read();
     96     }
     97     while (m--) {
     98         int o = read(), x = read(), y = read();
     99         if (o == 0) {
    100             split(x, y);
    101             printf("%d
    ", s[y]);
    102         } else if (o == 1) {
    103             link(x, y);
    104         } else if (o == 2) {
    105             cut(x, y);
    106         } else {
    107             splay(x);
    108             val[x] = y;
    109         }
    110     }
    111     return 0;
    112 }
    View Code
  • 相关阅读:
    【笔记】C++自学笔记系列02:类的组合与类的友元
    【windows程序设计】系列02:显示屏幕分辨率
    【笔记】C++自学笔记系列01:基础知识
    【windows程序设计】系列03:窗口与消息
    【windows程序设计】系列04:文本输出
    【Boost】系列05:数值与字符串转换
    【windows程序设计】系列01
    【Boost】系列04:实用技巧之禁止类拷贝构造和赋值
    【gdb】基本操作
    性能测试基本流程介绍(《软件性能测试过程详解与安全剖析》)
  • 原文地址:https://www.cnblogs.com/Sundial/p/12263951.html
Copyright © 2020-2023  润新知