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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章