zoukankan      html  css  js  c++  java
  • HDU 3478 Play with Chain (Splay树)

    这种高级数据结构太难搞了.........现在还是先照着别人的代码敲,做模板..........慢慢花时间来弄懂


    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <set>
    #include <queue>
    #include <stack>
    #include <climits>//形如INT_MAX一类的
    #define MAX 301111
    #define INF 0x7FFFFFFF
    #define REP(i,s,t) for(int i=(s);i<=(t);++i)
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define mp(a,b) make_pair(a,b)
    #define LL(x) x<<1
    #define RR(x) x<<1|1
    # define eps 1e-5
    //#pragma comment(linker, "/STACK:36777216") ///传说中的外挂
    using namespace std;
    
    int n,q,root,tot,cnt;
    int size[MAX],ch[MAX][2],key[MAX],pre[MAX],num[MAX],lazy[MAX],node[MAX];
    
    void newnode(int &x, int va,int fa) {
        x = ++ tot;
        ch[x][0] = ch[x][1] = 0;
        pre[x] = fa;
        lazy[x] = 0;
        key[x] = va;
    }
    
    void up(int x) {
        size[x] = size[ch[x][0]] + size[ch[x][1]] + 1;
    }
    
    void down(int x) {
        if(lazy[x]) {
            swap(ch[x][0],ch[x][1]);
            lazy[ch[x][0]] ^= 1;
            lazy[ch[x][1]] ^= 1;
            lazy[x] = 0;
        }
    }
    
    void build(int &x,int L,int R,int fa) {
        if(L > R) return ;
        int mid = (L + R) >> 1;
        newnode(x,mid,fa);
        build(ch[x][0],L,mid-1,x);
        build(ch[x][1],mid+1,R,x);
        up(x);
    }
    
    void init() {
        root = tot = 0;
        ch[0][0] = ch[0][1] = pre[0] = lazy[0] = size[0] = 0;
        newnode(root,-1,0);
        newnode(ch[root][1],-1,root);
        size[root] = 2;
        build(ch[ch[root][1]][0],1,n,ch[root][1]);
        up(ch[root][1]);
        up(root);
    }
    
    void rotate(int x,int kind) { // 0 :左旋 1:右旋
        int y = pre[x];
        down(y);
        down(x);
        ch[y][!kind] = ch[x][kind];
        pre[ch[x][kind]] = y;
        if(pre[y]) ch[pre[y]][ch[pre[y]][1] == y] = x;
        pre[x] = pre[y];
        ch[x][kind] = y;
        pre[y] = x;
        up(y);
    }
    
    void splay(int x,int g) {
        down(x);
        while(pre[x] != g) {
            if(pre[pre[x]] == g) rotate(x,ch[pre[x]][0] == x);
            else {
                int y = pre[x];
                int kind = (ch[pre[y]][0] == y);
                if(ch[y][kind] == x) {
                    rotate(x,!kind) ;
                    rotate(x,kind);
                } else {
                    rotate(y,kind);
                    rotate(x,kind);
                }
            }
        }
        up(x);
        if(g == 0) root = x;
    }
    
    int get_kth(int x,int k) {
        down(x);
        int s = size[ch[x][0]];
        if(s == k-1) return x;
        if(s >= k) return get_kth(ch[x][0],k);
        else return get_kth(ch[x][1],k-s-1);
    }
    
    int get_min(int x) {
        down(x);
        while(ch[x][0]) {
            x = ch[x][0];
            down(x);
        }
        return x;
    }
    
    int get_max(int x) {
        down(x);
        while(ch[x][1]) {
            x = ch[x][1];
            down(x);
        }
        return x;
    }
    
    int get_pre(int x) {
        int now = ch[x][0];
        while(ch[now][1]) {
            now = ch[now][1];
        }
        return now;
    }
    
    int get_suc(int x) {
        int now = ch[x][1];
        while(ch[now][0]) {
            now = ch[now][0];
        }
        return now;
    }
    
    void rev(int l,int r) {
        int x = get_kth(root,l);
        int y = get_kth(root,r+2);
        splay(x,0);
        splay(y,root);
        lazy[ch[ch[root][1]][0]] ^= 1;
    }
    
    void cut(int l,int r,int c) {
        int x = get_kth(root,l);
        int y = get_kth(root,r+2);
        splay(x,0);
        splay(y,root);
        int tmp = ch[ch[root][1]][0];
        ch[ch[root][1]][0] = 0;
        up(ch[root][1]);
        up(root);
        int z = get_kth(root,c+1);
        splay(z,0);
        int m = get_min(ch[root][1]);
        splay(m,root);
        ch[ch[root][1]][0] = tmp;
        pre[ch[ch[root][1]][0]] = ch[root][1];
        up(ch[root][1]);
        up(root);
    }
    
    void print(int x) {
        if(x == 0) return ;
        down(x);
        print(ch[x][0]);
        if(cnt >= 1 && cnt <= n) {
            if(cnt > 1) printf(" ");
            printf("%d",key[x]);
        }
        cnt ++;
        print(ch[x][1]);
    }
    
    char str[11];
    int a,b,c;
    int main() {
        while(scanf("%d%d",&n,&q) != EOF) {
            if(n == -1 && q == -1) break;
            init();
            while(q--) {
                scanf("%s",str);
                if(str[0] == 'C') {
                    scanf("%d%d%d",&a,&b,&c);
                    cut(a,b,c);
                }
                if(str[0] == 'F') {
                    scanf("%d%d",&a,&b);
                    rev(a,b);
                }
            }
            cnt = 0;
            print(root);
            puts("");
        }
        return 0;
    }
    


  • 相关阅读:
    洛谷P1446/BZOJ1004 Cards Burnside引理+01背包
    HDU-4676 Sum Of Gcd 莫队+欧拉函数
    HDU-5378 概率DP
    HDU-5628 Clarke and math-狄利克雷卷积+快速幂
    容斥原理+补集转化+MinMax容斥
    2019牛客暑期多校训练营(第九场)A.The power of Fibonacci
    斐波那契额数列的性质
    莫比乌斯反演/线性筛/积性函数/杜教筛/min25筛 学习笔记
    广义Fibonacci数列找循环节 学习笔记
    苗条的生成树 Slim Span--洛谷
  • 原文地址:https://www.cnblogs.com/pangblog/p/3293876.html
Copyright © 2011-2022 走看看