POJ3580 SuperMemo

Posted autoint

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ3580 SuperMemo相关的知识,希望对你有一定的参考价值。

题意

Language:
SuperMemo
Time Limit: 5000MSMemory Limit: 65536K
Total Submissions: 19516Accepted: 6133
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

分析

没什么好说的,毒瘤数据结构,Treap维护即可。

时间复杂度(O((n+m)log n))

代码

无力维护码风的,写得要吐了。

#include<iostream>
#include<cstring>
#include<vector>
#include<string>
#include<cstdlib>
#include<cassert>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;rg char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
    while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;

co int N=2e5+1;
int root,tot;
std::vector<int> bin;
int ch[N][2],siz[N],pri[N];
int val[N],min[N],plus[N],rev[N];
il int newnode(int v){
    int x;
    if(bin.size()) x=bin.back(),bin.pop_back();
    else x=++tot;
    ch[x][0]=ch[x][1]=0,siz[x]=1,pri[x]=rand();
    val[x]=min[x]=v,plus[x]=rev[x]=0;
    return x;
}
il void up(int x){
    siz[x]=1,min[x]=val[x];
    for(int i=0;i<2;++i)if(ch[x][i])
        siz[x]+=siz[ch[x][i]],min[x]=std::min(min[x],min[ch[x][i]]);
}
il void add(int x,int v){
    val[x]+=v,min[x]+=v,plus[x]+=v;
}
il void rever(int x){
    std::swap(ch[x][0],ch[x][1]),rev[x]^=1;
}
il void down(int x){
    if(plus[x]){
        for(int i=0;i<2;++i)if(ch[x][i])
            add(ch[x][i],plus[x]);
        plus[x]=0;
    }
    if(rev[x]){
        for(int i=0;i<2;++i)if(ch[x][i])
            rever(ch[x][i]);
        rev[x]=0;
    }
}
int merge(int x,int y){
    if(!x||!y) return x+y;
    if(pri[x]>pri[y])
        return down(x),ch[x][1]=merge(ch[x][1],y),up(x),x;
    else
        return down(y),ch[y][0]=merge(x,ch[y][0]),up(y),y;
}
void split(int x,int k,int&l,int&r){
    if(!x) return l=r=0,void();
    if(siz[ch[x][0]]+1<=k)
        return l=x,down(l),split(ch[l][1],k-siz[ch[l][0]]-1,ch[l][1],r),up(l);
    else
        return r=x,down(r),split(ch[r][0],k,l,ch[r][0]),up(r);
}
//void debug(int t){
//  if(!t) return;
//  fprintf(stderr,"%d l=%d r=%d v=%d m=%d
",t,ch[t][0],ch[t][1],val[t],min[t]);
//  debug(ch[t][0]),debug(ch[t][1]);
//}
int main(){
//  freopen(".in","r",stdin),freopen(".out","w",stdout);
    srand(20030506);
    for(int n=read<int>();n--;) root=merge(root,newnode(read<int>()));
    for(int m=read<int>();m--;){
        std::string o;std::cin>>o;
        if(o=="ADD"){
            int x,y,D;
            read(x),read(y),read(D);
            int l,r;
            split(root,y,root,r),split(root,x-1,l,root);
            add(root,D);
            root=merge(l,merge(root,r));
        }
        else if(o=="REVERSE"){
            int x,y;
            read(x),read(y);
            int l,r;
            split(root,y,root,r),split(root,x-1,l,root);
            rever(root);
            root=merge(l,merge(root,r));
        }
        else if(o=="REVOLVE"){
            int x,y,T;
            read(x),read(y),read(T);
            if(!(T%=(y-x+1))) continue;
            int l,m,r;
            split(root,y,root,r),split(root,x-1,l,root);
            split(root,siz[root]-T,root,m);
            root=merge(l,merge(m,merge(root,r)));
        }
        else if(o=="INSERT"){
            int x,P;
            read(x),read(P);
            int l;
            split(root,x,l,root);
            root=merge(l,merge(newnode(P),root));
        }
        else if(o=="DELETE"){
            int x;
            read(x);
            int l,r;
            split(root,x,root,r),split(root,x-1,l,root);
            bin.push_back(root);
            root=merge(l,r);
        }
        else if(o=="MIN"){
            int x,y;
            read(x),read(y);
            int l,r;
            split(root,y,root,r),split(root,x-1,l,root);
            printf("%d
",min[root]);
            root=merge(l,merge(root,r));
        }
        else assert(0);
    }
    return 0;
}

以上是关于POJ3580 SuperMemo的主要内容,如果未能解决你的问题,请参考以下文章

Poj 3580-SuperMemo Splay

POJ3580:SuperMemo

POJ 3580 - SuperMemo - [伸展树splay]

POJ3580 SuperMemo

平衡树:Splaytree POJ 3580 SuperMemo

POJ 3580SuperMemo