LCT模板(指针版)

本来是想做THUWC2017的泰勒展开xLCT题的……
然后觉得数组写很麻烦……
然后就决定挑战指针版……
然后写得全是BUG……

与BUG鏖战三千年后,有了这个指针版LCT板子!

#include 
#include 
#include 
#include 
#include 
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
typedef long long ll;
template 
void read(T &x){
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
    if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
    x = x * 10 + c - '0';
    if(op) x = -x;
}
template 
void write(T x){
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}

typedef long double ldb;
const int N = 300005;
int n, m;
struct node {
    node *fa, *ch[2];
    int val, sum;
    bool rev;
    node(){
    fa = ch[0] = ch[1] = NULL;
    val = sum = 0;
    rev = 0;
    }
    bool which(){
    return fa->ch[1] == this;
    }
    bool isroot(){
    return fa == NULL || (fa->ch[0] != this && fa->ch[1] != this);
    }
    void upt(){
    sum = val;
    if(ch[0] != NULL) sum ^= ch[0]->sum;
    if(ch[1] != NULL) sum ^= ch[1]->sum;
    }
    void pushdown(){
    if(!rev) return;
    swap(ch[0], ch[1]);
    if(ch[0] != NULL) ch[0]->rev ^= 1;
    if(ch[1] != NULL) ch[1]->rev ^= 1;
    rev = 0;
    }
} s[N];

void rotate(node *u){
    node *v = u->fa, *w = v->fa, *b = u->ch[!u->which()];
    if(!v->isroot()) w->ch[v->which()] = u;
    u->which() ? (u->ch[0] = v, v->ch[1] = b) : (u->ch[1] = v, v->ch[0] = b);
    u->fa = w, v->fa = u;
    if(b != NULL) b->fa = v;
    v->upt();
}
void splay(node *u){
    static node *stk[N];
    int top;
    stk[top = 1] = u;
    while(!stk[top]->isroot()) stk[top + 1] = stk[top]->fa, top++;
    while(top) stk[top--]->pushdown();
    while(!u->isroot()){
    if(!u->fa->isroot()){
        if(u->which() == u->fa->which()) rotate(u->fa);
        else rotate(u);
    }
    rotate(u);
    }
    u->upt();
}
void access(node *u){
    node *v = NULL;
    while(u != NULL){
    splay(u);
    u->ch[1] = v;
    u->upt();
    v = u;
    u = u->fa;
    }
}
void makeroot(node *u){
    access(u);
    splay(u);
    u->rev ^= 1;
}
node *findroot(node *u){
    access(u);
    splay(u);
    while(u->pushdown(), u->ch[0] != NULL)
    u = u->ch[0];
    splay(u);
    return u;
}
void link(node *u, node *v){
    if(findroot(u) == findroot(v)) return;
    makeroot(v);
    v->fa = u;
}
void cut(node *u, node *v){
    makeroot(u);
    access(v);
    splay(v);
    if(v->ch[0] == u)
    v->ch[0] = u->fa = NULL;
}
int query(node *u, node *v){
    makeroot(u);
    access(v);
    splay(v);
    return v->sum;
}
void change(node *u, int x){
    splay(u);
    u->val = x;
    u->upt();
}

int main(){

    read(n), read(m);
    for(int i = 1; i <= n; i++)
    read(s[i].val), s[i].upt();
    int op, x, y;
    while(m--){
    read(op), read(x), read(y);
    if(op == 0) write(query(s + x, s + y)), enter;
    else if(op == 1) link(s + x, s + y);
    else if(op == 2) cut(s + x, s + y);
    else change(s + x, y);
    }

    return 0;
}

你可能感兴趣的:(LCT模板(指针版))