poj 3580(Splay)


SuperMemo
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 14372   Accepted: 4489
Case Time Limit: 2000MS

Description

Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a memorizing game. At first, the host tells the participant a sequence of numbers, {A1, A2, ... An}. Then the host performs a series of operations and queries on the sequence which consists:

  1. ADD x y D: Add D to each number in sub-sequence {Ax ... Ay}. For example, performing "ADD 2 4 1" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5, 5}
  2. REVERSE x y: reverse the sub-sequence {Ax ... Ay}. For example, performing "REVERSE 2 4" on {1, 2, 3, 4, 5} results in {1, 4, 3, 2, 5}
  3. REVOLVE x y T: rotate sub-sequence {Ax ... Ay} T times. For example, performing "REVOLVE 2 4 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 2, 5}
  4. INSERT x P: insert P after Ax. For example, performing "INSERT 2 4" on {1, 2, 3, 4, 5} results in {1, 2, 4, 3, 4, 5}
  5. DELETE x: delete Ax. For example, performing "DELETE 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5}
  6. MIN x y: query the participant what is the minimum number in sub-sequence {Ax ... Ay}. For example, the correct answer to "MIN 2 4" on {1, 2, 3, 4, 5} is 2

To make the show more interesting, the participant is granted a chance to turn to someone else that means when Jackson feels difficult in answering a query he may call you for help. You task is to watch the TV show and write a program giving the correct answer to each query in order to assist Jackson whenever he calls.

Input

The first line contains n (n ≤ 100000).

The following n lines describe the sequence.

Then follows M (M ≤ 100000), the numbers of operations and queries.

The following M lines describe the operations and queries.

Output

For each "MIN" query, output the correct answer.

Sample Input

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

Sample Output

5

Source


代碼上參照了cxlove大神的版,原文鏈接:http://blog.csdn.net/acm_cxlove/article/details/7803646
splay模板題;
參考:OI2007餘江偉《如何處理好動態統計問題》
OI2004 楊思雨《伸展樹的基本操作和應用》
平衡樹之splay講解  http://www.cnblogs.com/BLADEVIL/p/3464458.html
另外還有維基百科上關於Splay的講解


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAXN 200005
#define inf 1<<29
#define key_value (ch[ch[root][1]][0])
using namespace std;
int n,q,a[MAXN];
int m[MAXN],rev[MAXN],size[MAXN],add[MAXN],pre[MAXN],ch[MAXN][2],val[MAXN];
int tot1,tot2,root,s[MAXN];
void update_rev(int r)
{
    if(!r) return;
    swap(ch[r][0],ch[r][1]);
    rev[r]^=1;
}
void update_add(int r,int ADD)
{
    if(!r) return;
    m[r]+=ADD;
    val[r]+=ADD;
    add[r]+=ADD;
}
void newnode(int &r,int k,int father)
{
    if(tot2)
        r=s[tot2--];
    else
        r=++tot1;
    ch[r][0]=ch[r][1]=0;
    pre[r]=father;
    val[r]=m[r]=k;
    size[r]=1;
    add[r]=0;
}
void push_up(int x)
{
    int l=ch[x][0],r=ch[x][1];
    size[x]=size[l]+size[r]+1;
    m[x]=min(min(m[l],m[r]),val[x]);
}
void push_down(int x)
{
    int l=ch[x][0],r=ch[x][1];
    if(add[x])
    {
       update_add(l,add[x]);
       update_add(r,add[x]);
       add[x]=0;
    }
    if(rev[x])
    {
        update_rev(l);
        update_rev(r);
        rev[x]=0;
    }
}
void build(int &r,int L,int R,int father)
{
    if(L>R)
        return;
    int mid=(L+R)/2;
    newnode(r,a[mid],father);
    build(ch[r][0],L,mid-1,r);
    build(ch[r][1],mid+1,R,r);
    push_up(r);
}
void Init()
{
    tot1=tot2=root=0;
    ch[root][0]=ch[root][1]=pre[root]=rev[root]=size[root]=add[root]=0;
    m[root]=inf;
    newnode(root,inf,0);
    newnode(ch[root][1],inf,root);
    push_up(root);
    build(key_value,1,n,ch[root][1]);
    push_up(ch[root][1]);
    push_up(root);
}
void rotate(int x,int kind)
{
    int y=pre[x];
    push_down(y);
    push_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;  
    push_up(y);
}
void Splay(int r,int goal)
{  
    push_down(r);
    while(pre[r]!=goal)
    {  
        if(pre[pre[r]]==goal)  
            rotate(r,ch[pre[r]][0]==r);  
        else
        {  
            int y=pre[r];  
            int kind=(ch[pre[y]][0]==y);  
            if(ch[y][kind]==r)
            {  
                rotate(r,!kind);  
                rotate(r,kind);  
            }  
            else
            {  
                rotate(y,kind);  
                rotate(r,kind);  
            }  
        }  
    }  
    push_up(r);  
    if(goal==0) root=r;
}
int get_kth(int r,int k)
{
    push_down(r);
    int t=size[ch[r][0]]+1;
    if(t==k)
        return r;
    if(t>k)
        return get_kth(ch[r][0],k);
    else
        return get_kth(ch[r][1],k-t);
}
int get_min(int r)
{
    push_down(r);
    while(ch[r][0])
    {
        r=ch[r][0];
        push_down(r);
    }
    return r;
}
void reversal(int l,int r)
{
    int x=get_kth(root,l);
    Splay(x,0);
    int y=get_kth(root,r+2);
    Splay(y,root);
    update_rev(key_value);
}
void insert(int pos,int k)
{
    int x=get_kth(root,pos);
    Splay(x,0);
    int y=get_min(ch[root][1]);
    Splay(y,root);
    newnode(key_value,k,ch[root][1]);
    push_up(ch[root][1]);
    push_up(root);
}
void erase(int r)
{
    if(!r) return;
    s[++tot2]=r;
    erase(ch[r][0]);
    erase(ch[r][1]);
}
void ADD(int l,int r,int k)
{
    int x=get_kth(root,l);
    Splay(x,0);
    int y=get_kth(root,r+2);
    Splay(y,root);
    update_add(key_value,k);
    push_up(ch[root][1]);
    push_up(root);
}
int ans(int l,int r)
{
    int x=get_kth(root,l);
    Splay(x,0);
    int y=get_kth(root,r+2);
    Splay(y,root);
    return m[key_value];
}
void revolve(int a,int b,int t)
{
    if(!t)
        return;
    int c=b-t;
    int x=get_kth(root,a);
    Splay(x,0);
    x=get_kth(root,c+2);
    Splay(x,root);
    int tmp=key_value;
    key_value=0;
    push_up(ch[root][1]);
    push_up(root);
    Splay(get_kth(root,b-c+a),0);
    Splay(get_kth(root,b-c+a+1),root);
    key_value=tmp;
    pre[key_value]=ch[root][1];
    push_up(ch[root][1]);
    push_up(root);
}
void Delete(int l)
{
    int x=get_kth(root,l);
    Splay(x,0); 
    int y=get_kth(root,l+2);
    Splay(y,root);
    erase(key_value);
    pre[key_value]=0;
    key_value=0;
    push_up(ch[root][1]);
    push_up(root);
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        scanf("%d",&q);
        Init();
        char str[10];
        int l,r,k;
        while(q--){
            scanf("%s",str);
            if(!strcmp(str,"ADD")){
                scanf("%d%d%d",&l,&r,&k);
                ADD(l,r,k);
            }
            else if(!strcmp(str,"REVERSE")){
                scanf("%d%d",&l,&r);
                reversal(l,r);
            }
            else if(!strcmp(str,"REVOLVE")){
                scanf("%d%d%d",&l,&r,&k);
                revolve(l,r,(k%(r-l+1)+(r-l+1))%(r-l+1));
            }
            else if(!strcmp(str,"INSERT")){
                scanf("%d%d",&l,&k);
                insert(l+1,k);
            }
            else if(!strcmp(str,"DELETE")){
                scanf("%d",&l);
                Delete(l);
            }
            else{
                scanf("%d%d",&l,&r);
                printf("%d\n",ans(l,r));
            }
        }
    }
    return 0;
}

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