[POJ3580]SuperMemo(无旋Treap)

SuperMemo

Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 17538 Accepted: 5496
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 {AxAy}. 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 {AxAy}. 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 {AxAy} 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 {AxAy}. 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

思路&&分析

    这题其实直接上无旋Treap就行了。需要注意的是Revolve那个操作中T有可能是负的,或者T%(y-x+1)==0,也就是不动。而且这题没有写数据范围,于是我刚开始#define int long long了,结果T掉了,后来去掉之后稍微改了下inf就过了……

Code

#pragma GCC optimize(3)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cctype>
#include<climits>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<stack>
#include<climits>
#include<vector>
//#define int long long
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
/*================Header Template==============*/
typedef pair<int,int> Pii;
#define mp make_pair
#define x first
#define y second
const int base=48271,maxn=200005;
int seed=233,cnt,rt;
inline int Rand() {
    return seed=(int)(1ll*seed*base%INT_MAX);
}
struct Treap {
    int val,sz,ls,rs,tag,rev,fix,mn;
    Treap(int _val=0):val(_val){ls=rs=sz=tag=rev=0,fix=Rand();} 
}tr[maxn];
inline void Newnode(int val) {
    tr[++cnt]=Treap(val);
    tr[cnt].sz=1;
}
inline int Sz(int o) {
    return o?tr[o].sz:0;
}
inline int Mn(int o) {
    return o?tr[o].mn:1073741823;
}
inline int Tag(int o) {
    return o?tr[o].tag:1073741823;
}
inline void Pushup(int o) {
    tr[o].sz=Sz(tr[o].ls)+1+Sz(tr[o].rs);
    tr[o].mn=min(tr[o].val,min(Mn(tr[o].ls)+Tag(tr[o].ls),Mn(tr[o].rs)+Tag(tr[o].rs)));
}
inline void Pushdown(int o) {
    if(tr[o].rev) {
        if(tr[o].ls)
            tr[tr[o].ls].rev^=1;
        if(tr[o].rs)
            tr[tr[o].rs].rev^=1;
        swap(tr[o].ls,tr[o].rs);
        tr[o].rev=0;
    }
    if(tr[o].tag) {
        tr[o].val+=tr[o].tag;
        tr[o].mn+=tr[o].tag;
        if(tr[o].ls)
            tr[tr[o].ls].tag+=tr[o].tag;
        if(tr[o].rs)
            tr[tr[o].rs].tag+=tr[o].tag;
        tr[o].tag=0;
    }
    Pushup(o);
}
inline int Merge(int a,int b) {
    if(!a||!b)
        return a|b;
    Pushdown(a),Pushdown(b);
    if(tr[a].fix<tr[b].fix) {
        tr[a].rs=Merge(tr[a].rs,b);
        Pushup(a);
        return a;
    }
    else {
        tr[b].ls=Merge(a,tr[b].ls);
        Pushup(b);
        return b;
    }
}
inline Pii Split(int o,int k) {
    if(!o)
        return mp(0,0);
    Pushdown(o);
    if(Sz(tr[o].ls)==k) {
        int pre=tr[o].ls;
        tr[o].ls=0;
        Pushup(o);
        return mp(pre,o);
    }
    if(Sz(tr[o].ls)+1==k) {
        int pre=tr[o].rs;
        tr[o].rs=0;
        Pushup(o);
        return mp(o,pre);
    }
    if(Sz(tr[o].ls)>k) {
        Pii tmp=Split(tr[o].ls,k);
        tr[o].ls=tmp.y;
        Pushup(o);
        return mp(tmp.x,o);
    }
    Pii tmp=Split(tr[o].rs,k-Sz(tr[o].ls)-1);
    tr[o].rs=tmp.x;
    Pushup(o);
    return mp(o,tmp.y); 
}
inline void Add(int o,int l,int r,int d) {
    Pii tmp1=Split(o,r),tmp2=Split(tmp1.x,l-1);
    if(tmp2.y)
        tr[tmp2.y].tag+=d;
    rt=Merge(Merge(tmp2.x,tmp2.y),tmp1.y);
}
inline void Reverse(int o,int l,int r) {
    Pii tmp1=Split(o,r),tmp2=Split(tmp1.x,l-1);
    if(tmp2.y)
        tr[tmp2.y].rev^=1;
    rt=Merge(Merge(tmp2.x,tmp2.y),tmp1.y);
}
inline void Revolve(int o,int l,int r,int t) {
    int k=r-l+1;
    t=(t%k+k)%k;
    if(t==0)
        return;
    Pii tmp1=Split(o,r),tmp2=Split(tmp1.x,l-1);
    Pii tmp3=Split(tmp2.y,k-t);
    rt=Merge(Merge(Merge(tmp2.x,tmp3.y),tmp3.x),tmp1.y);
}
inline void Insert(int o,int pos,int k) {
    Pii tmp=Split(o,pos);
    Newnode(k);
    rt=Merge(Merge(tmp.x,cnt),tmp.y);
}
inline void Delete(int o,int xx) {
    Pii tmp1=Split(o,xx),tmp2=Split(tmp1.x,xx-1);
    rt=Merge(tmp2.x,tmp1.y);
}
inline void Min(int o,int l,int r) {
    Pii tmp1=Split(o,r),tmp2=Split(tmp1.x,l-1);
    Pushdown(tmp2.y);
    printf("%d\n",tr[tmp2.y].mn);
    rt=Merge(Merge(tmp2.x,tmp2.y),tmp1.y);
}
signed main() {
    int n,q;
    read(n);
    for(int i=1;i<=n;i++) {
        int x;
        read(x);
        Insert(rt,i-1,x);
    }
    read(q);
    while(q--) {
        char op[10];
        scanf("%s",op);
        if(op[0]=='A') {
            int xx,yy,d;
            read(xx),read(yy),read(d);
            Add(rt,xx,yy,d);
        }
        if(op[0]=='R') {
            int xx,yy;
            read(xx);read(yy);
            if(op[3]=='E')
                Reverse(rt,xx,yy);
            else {
                int T;
                read(T);
                Revolve(rt,xx,yy,T);
            }
        }
        if(op[0]=='I') {
            int xx,p;
            read(xx),read(p);
            Insert(rt,xx,p);
        }
        if(op[0]=='D') {
            int xx;
            read(xx);
            Delete(rt,xx);
        }
        if(op[0]=='M') {
            int xx,yy;
            read(xx),read(yy);
            Min(rt,xx,yy);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/effervescence/article/details/79488836