POJ3580 SuperMemo
Posted autoint
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ3580 SuperMemo相关的知识,希望对你有一定的参考价值。
题意
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 19516 | Accepted: 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:
- 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}
- 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}
- 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}
- 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}
- DELETE x: delete Ax. For example, performing "DELETE 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5}
- 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]