zoukankan      html  css  js  c++  java
  • LCT模板(指针版)

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

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

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #define space putchar(' ')
    #define enter putchar('
    ')
    using namespace std;
    typedef long long ll;
    template <class T>
    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 <class T>
    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;
    }
    
    
  • 相关阅读:
    Dialog 不能全屏,左右有间距解决方案
    mac apktool配置
    HTML5网站如何做到完全不需要jQuery
    js中控制小数点的显示位数的技术整理
    ASP.NET后台获取cookie中文乱码解决办法
    javascript删除元素节点
    js获取不到动态添加的标签的值的解决方法
    JS常用方法函数整理
    JS获取当前页面的URL信息
    轻轻松松 用U盘安装WIN7
  • 原文地址:https://www.cnblogs.com/RabbitHu/p/9078053.html
Copyright © 2011-2022 走看看