poj 3580 经典splay树

/*
这个写得有点吐血,,,,,,,,,不过确实经典 ,,,,,
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define keyTree (ch[ ch[root][1] ][0])
int const inf = 0x3f3f3f3f;
using namespace std;
const int maxn = 222222 ;
struct SplayTree{
int sz[maxn];
int ch[maxn][2];
int pre[maxn];
int root , top1 , top2;
int ss[maxn] , que[maxn];
    int flag[maxn];
inline void Rotate(int x,int f) {
int y = pre[x];
push_down(y);
push_down(x);
ch[y][!f] = ch[x][f];
pre[ ch[x][f] ] = y;
pre[x] = pre[y];
if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] = x;
ch[x][f] = y;
pre[y] = x;
push_up(y);
}
inline void Splay(int x,int goal) {
push_down(x);
while(pre[x] != goal) {
        push_down(pre[pre[x]]); push_down(pre[x]);push_down(x);
if(pre[pre[x]] == goal) {
Rotate(x , ch[pre[x]][0] == x);
} else {
int y = pre[x] , z = pre[y];
int f = (ch[z][0] == y);
if(ch[y][f] == x) {
Rotate(x , !f) , Rotate(x , f);
} else {
Rotate(y , f) , Rotate(x , f);
}
}
}
push_up(x);
if(goal == 0) root = x;
}
inline void RotateTo(int k,int goal) {
int x = root;
push_down(x);
while(sz[ ch[x][0] ] != k) {
if(k < sz[ ch[x][0] ]) {
x = ch[x][0];
} else {
k -= (sz[ ch[x][0] ] + 1);
x = ch[x][1];
}
push_down(x);
}
Splay(x,goal);
}
inline void erase(int x) {
int father = pre[x];
ch[ father ][ ch[father][1] == x ] = 0;
push_up(father);push_up(root);
}
inline void push_down(int x) {
   if(flag[x]){
            if(ch[x][0])
            flag[ ch[x][0] ] ^=1;
            if(ch[x][1])
            flag[ ch[x][1] ] ^=1;
            swap(ch[x][0],ch[x][1]);
            flag[x]^=1;
   }
if(add[x]) {
if(ch[x][0]>=1){
add[ ch[x][0] ] += add[x];
val[ ch[x][0] ]+=add[x];
       Min[ch[x][0]] += add[x];
  }
  if(ch[x][1]>=1){
add[ ch[x][1] ] += add[x];
            val[ ch[x][1] ]+=add[x];
Min[ch[x][1]] += add[x];
  }
add[x] = 0;
}
}
inline void push_up(int x) {
sz[x] = 1 + sz[ ch[x][0] ] + sz[ ch[x][1] ];
Min[x]=min(val[x],min(Min[ ch[x][0]],Min[ch[x][1]]));
       }
    inline void NewNode(int &x,int c) {
        x = ++top1;
ch[x][0] = ch[x][1] = pre[x] = 0;
sz[x] = 1;
        flag[x]=0;
Min[x] = val[x]  = c;
add[x] = 0;
}

inline void makeTree(int &x,int l,int r,int f) {
if(l > r) return ;
int m = (l + r)>>1;
NewNode(x , num[m]);
makeTree(ch[x][0] , l , m - 1 , x);
makeTree(ch[x][1] , m + 1 , r , x);
pre[x] = f;
push_up(x);
}
void insert(int c,int f){
  NewNode(ch[f][0],c);
  pre[ch[f][0]]=f;
  push_up(f);
  push_up(root);
}

inline void init(int n) {
ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0;
add[0]  = 0;
Min[0]=inf;
root = top1 = 0;
NewNode(root , inf);
NewNode(ch[root][1] , inf);
pre[top1] = root;
sz[root] = 2;
for (int i = 0 ; i < n ; i ++)  scanf("%d",&num[i]);
makeTree(keyTree , 0 , n-1 , ch[root][1]);
push_up(ch[root][1]);
push_up(root);
}
    void update(){
      char ss[30];
      scanf("%s",ss);
      int l,r,c;
      if(ss[0]=='A'){
        scanf("%d%d%d",&l,&r,&c);
        if(l>r) swap(l,r);
        RotateTo(l-1,0);
        RotateTo(r+1,root);
        add[ keyTree ] +=c;
        Min[ keyTree] += c;
        val[keyTree] += c;
      }
      if(ss[0]=='M'){
        scanf("%d%d",&l,&r);
        if(l>r) swap(l,r);
        RotateTo(l-1,0);
        RotateTo(r+1,root);
        printf("%d\n",Min[keyTree]);
      }
      if(ss[0]=='D'){
        scanf("%d",&c);
        RotateTo(c-1,0);
        RotateTo(c+1,root);
        erase(ch[ch[root][1]][0]);
      }
      if(ss[0]=='I'){
        scanf("%d%d",&l,&c);
        RotateTo(l,0);
        RotateTo(l+1,root);
        insert(c,ch[root][1]);
      }
      if(ss[0]=='R'){
        if(ss[3]=='E'){
            scanf("%d%d",&l,&r);
            if(l>r) swap(l,r);
            RotateTo(l-1,0);
            RotateTo(r+1,root);
            flag[keyTree]^=1;
        }
        else {
            scanf("%d%d%d",&l,&r,&c);
            if(l>r) swap(l,r);
            c=c%(r-l+1);
            if(c<0) c+=(r-l+1);
            if(c==0) return;
            int ll=r-c+1,rr=r;
            RotateTo(ll-1,0);
            RotateTo(rr+1,root);
            int t =keyTree;
            erase(ch[ch[root][1]][0]);
            RotateTo(l-1,0);
            RotateTo(l,root);
            ch[ch[root][1]][0] = t;
            pre[keyTree]=ch[root][1];
       push_up(ch[root][1]);
            push_up(root);
        }
      }
    }
int num[maxn];
int val[maxn];
int add[maxn];
int Min[maxn];
}spt;

int main() {
int n , m;
    while(~scanf("%d",&n)){
spt.init(n);
cin>>m;
while(m--){
        spt.update();
}
return 0;
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值