poj3580(splay 毒瘤题)

3: Lydsy1895 SuperMemo

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 15  Solved: 11
[Submit][Status][Web Board]

Description

给出一个初始序列fA1;A2;:::Ang,要求你编写程序支持如下操作: 
1. ADDxyD:给子序列fAx:::Ayg的每个元素都加上D。例如对f1,2, 3,4,5g执行"ADD 241" 会得到f1,3,4,5,5g。 
2. REVERSExy:将子序列fAx:::Ayg翻转。例如对f1,2,3,4,5g执行"REVERSE 24"会得到f1,4,3,2,5g。 
3. REVOLVExyT:将子序列fAx:::Ayg旋转T个单位。例如,对f1,2,3,4,5g执行"REVOLVE 242"会得到f1,3,4,2,5g。 
4. INSERTxP:在Ax后插入P。例如,对f1,2,3,4,5g执行"INSERT 24"会得到f1,2,4,3,4,5g。 
5. DELETEx:删去Ax。例如,对f1,2,3,4,5g执行"DELETE 2"会得到f1,3,4,5g。 
6. MINxy:查询子序列fAx:::Ayg中的最小元素。例如,对于序列f1, 2,3,4,5g,询问"MIN 24"的返回应为2。

Input

第一行包含一个整数n,表示初始序列的长度。
以下n行每行包含一个整数,描述初始的序列。
接下来一行包含一个整数m,表示操作的数目。以下m行每行描述一个操作。n,m<=10^6

Output

对于所有"MIN"操作,输出正确的答案,每行一个。

Sample Input

5
1
2
3
4
5
2
ADD 2 4 1
MIN 4 5

Sample Output

5

HINT

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define inf 2100000000
const int maxn=300000+10;

int a[maxn],f[maxn],ch[maxn][2],key[maxn],Min[maxn],Size[maxn],ver[maxn],add[maxn],root;
int sz;

void Clear(int x){
     f[x]=ch[x][0]=ch[x][1]=key[x]=Size[x]=Min[x]=ver[x]=add[x]=0;
}

int getself(int x){
     return ch[f[x]][1]==x;
}

void update(int x){
     Size[x]=Size[ch[x][0]]+Size[ch[x][1]]+1;
     Min[x]=key[x];
     if(ch[x][0]) Min[x]=min(Min[x],Min[ch[x][0]]);
     if(ch[x][1]) Min[x]=min(Min[x],Min[ch[x][1]]);
}

void pushdown(int x){
     if(x){
        if(ver[x]){
            ver[ch[x][0]]^=1;
            ver[ch[x][1]]^=1;
            swap(ch[x][0],ch[x][1]);
            ver[x]=0;
        }
        if(add[x]){
            add[ch[x][0]]+=add[x],add[ch[x][1]]+=add[x];
            Min[ch[x][0]]+=add[x],Min[ch[x][1]]+=add[x];
            key[ch[x][0]]+=add[x],key[ch[x][1]]+=add[x];
            add[x]=0;
        }
     }
}

int build(int l,int r,int fa){
    if(l>r) return 0;
    int mid=(l+r)>>1,now=++sz;
    f[sz]=fa,key[sz]=a[mid];
    int tl=build(l,mid-1,now);
    int tr=build(mid+1,r,now);
    ch[now][0]=tl;
    ch[now][1]=tr;
    update(now);
    return now;
}

int Find(int x){
    int now=root;
    while(1){
        pushdown(now);
        if(x<=Size[ch[now][0]])  now=ch[now][0];
        else {
            x-=Size[ch[now][0]];
            if(x==1) return now;
            now=ch[now][1];
            --x;
        }
    }
}

void Rotate(int x){
     pushdown(f[x]);
     pushdown(x);
     int old=f[x],oldf=f[old],which=getself(x);
     ch[old][which]=ch[x][which^1],f[ch[old][which]]=old;
     ch[x][which^1]=old;f[old]=x;
     f[x]=oldf;
     if(oldf){
        ch[oldf][ch[oldf][1]==old]=x;
     }
     update(old);
     update(x);
}

void splay(int x,int tar){
     for (int fa;(fa=f[x])!=tar;Rotate(x))
        if(f[fa]!=tar) Rotate( (getself(x)==getself(fa))?fa:x);
    if(!tar) root=x;
}

int main(){
    char s[20];
    int n,m;
    scanf("%d",&n);
    a[1]=-inf;
    a[n+2]=inf;
    int x,y,d;
    for (int i=1;i<=n;i++) scanf("%d",&a[i+1]);
    root=build(1,n+2,0);
    scanf("%d",&m);
    for (int i=1;i<=m;i++){
        scanf("%s",s);
        switch(s[0]){
           case 'A':
            {
              scanf("%d%d%d",&x,&y,&d);
              if(x>y) swap(x,y);
              int aa=Find(x);
              int bb=Find(y+2);
              splay(aa,0);
              splay(bb,aa);
              Min[ch[ch[root][1]][0]]+=d;
              key[ch[ch[root][1]][0]]+=d;
              add[ch[ch[root][1]][0]]+=d;
              update(ch[root][1]);
              update(root);
              break;
            }
           case 'R':
            {
                if(s[3]=='E'){
                    scanf("%d%d",&x,&y);
                    if(x==y) continue;
                    if(x>y) swap(x,y);
                    int aa=Find(x);
                    int bb=Find(y+2);
                    splay(aa,0);
                    splay(bb,aa);
                    ver[ch[ch[root][1]][0]]^=1;
                }
                else {
                    scanf("%d%d%d",&x,&y,&d);
                    if(x>y) swap(x,y);
                    d%=y-x+1;
                    if(!d) continue;
                    int aa=Find(y-d+1);
                    int bb=Find(y+2);
                    splay(aa,0);
                    splay(bb,aa);
                    int now=ch[ch[root][1]][0];
                    ch[ch[root][1]][0]=0;
                    update(ch[root][1]);
                    update(root);

                    aa=Find(x);
                    bb=Find(x+1);
                    splay(aa,0);
                    splay(bb,aa);
                    ch[ch[root][1]][0]=now;
                    f[now]=ch[root][1];
                    update(ch[root][1]);
                    update(root);
                }
                break;
            }
           case 'I':
            {
                scanf("%d%d",&x,&d);
                int aa=Find(x+1);
                int bb=Find(x+2);
                splay(aa,0);
                splay(bb,aa);
                ch[ch[root][1]][0]=++sz;
                f[sz]=ch[root][1];
                Size[sz]=1;
                key[sz]=d;
                Min[sz]=d;
                update(ch[root][1]);
                update(root);
                break;
            }
           case 'D':
               {
                 scanf("%d",&x);
                 int aa=Find(x);
                 int bb=Find(x+2);
                 splay(aa,0);
                 splay(bb,aa);
                 int del=ch[ch[root][1]][0];
                 Clear(del);
                 ch[ch[root][1]][0]=0;
                 update(ch[root][1]);
                 update(root);
                 break ;
               }
           case 'M':
            {
                scanf("%d%d",&x,&y);
                if(x>y) swap(x,y);
                int aa=Find(x);
                int bb=Find(y+2);
                splay(aa,0);
                splay(bb,aa);
                int ans=Min[ch[ch[root][1]][0]];
                printf("%d\n",ans);
                break;
            }
        }
    }
return 0;
}

 

posted @ 2018-06-22 12:01  lmjer  阅读(279)  评论(1编辑  收藏  举报