两种操作,在书堆上面再放一本书。
将书堆最上面k本书,反转。
因为反转位置和数量固定,其实可以用双端模拟,,,,但为了复习一下SPLAY还是麻烦一点的比较好,,,。。。。
271. Book Pile
time limit per test: 0.5 sec.
memory limit per test: 65536 KB
memory limit per test: 65536 KB
input: standard
output: standard
output: standard
There is a pile of N books on the table. Two types of operations are performed over this pile:
- a book is added to the top of the pile,
- top K books are rotated. If there are less than K books on the table, the whole pile is rotated.
First operation is denoted as ADD(S) where S is the name of the book, and the second operations is denoted as ROTATE.
The maximum number of books is no more than 40000. All book names are non-empty sequences of no more than 3 capital Latin letters. The names of the books can be non-unique.
- a book is added to the top of the pile,
- top K books are rotated. If there are less than K books on the table, the whole pile is rotated.
First operation is denoted as ADD(S) where S is the name of the book, and the second operations is denoted as ROTATE.
The maximum number of books is no more than 40000. All book names are non-empty sequences of no more than 3 capital Latin letters. The names of the books can be non-unique.
Input
The first line of input file contains 3 integer numbers N, M, K (0 <= N <= 40000; 0 <= M <= 100000; 0 <= K <= 40000). The following N lines are the names of the books in the pile before performing any operations. The book names are given in order from top book to bottom. Each of the following M lines contains the operation description.
Output
Output the sequence of books names in the pile after performing all operations. First line corresponds to the top book.
Sample test(s)
Input
2 3 2 A B ADD(C) ROTATE ADD(D)
Output
D
A
C
B
A
C
B
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
using namespace std;
#define MAXN 400000
char str[40010][6];
int next[MAXN];
struct nodes
{
int ch[2],f;
char key[7];
int size,w,col;
}node[MAXN];
int pos[MAXN];
void init()
{
for(int i=0;i<MAXN-10;i++)
next[i]=i+1;
}
int newnode(char * key)
{
int p=next[0];
next[0]=next[p];
strcpy(node[p].key,key);
node[p].w=node[p].size=1;
node[p].col=0;
node[p].ch[0]=node[p].ch[1]=node[p].f=0;
return p;
}
void delnode(int p)
{
next[p]=next[0];
next[0]=p;
}
struct spt
{
int root;
void clear()
{
root=0;
}
void rotate(int x,int c)
{
int y=node[x].f;
push_down(y);push_down(x);
node[y].ch[!c]=node[x].ch[c];
if(node[x].ch[c])
node[node[x].ch[c]].f=y;
node[x].f=node[y].f;
if(node[y].f)
{
if(node[node[y].f].ch[0]==y)
node[node[y].f].ch[0]=x;
else
node[node[y].f].ch[1]=x;
}
node[x].ch[c]=y;
node[y].f=x;
push_up(y);
if(y==root) root=x;
}
void splay(int x,int f)
{
push_down(x);
for(;node[x].f!=f;)
{
push_down(node[node[x].f].f);
push_down(node[x].f);
push_down(x);
if(node[node[x].f].f==f)
{
if(node[node[x].f].ch[0]==x)
rotate(x,1);
else
rotate(x,0);
}
else
{
int y=node[x].f;
int z=node[y].f;
if(node[z].ch[0]==y)
{
if(node[y].ch[0]==x)
rotate(y,1),rotate(x,1);
else
rotate(x,0),rotate(x,1);
}
else
{
if(node[y].ch[1]==x)
rotate(y,0),rotate(x,0);
else
rotate(x,1),rotate(x,0);
}
}
}
push_up(x);
if(!f) root=x;
}
void insertAt(int x,char *a)
{
int p=newnode(a);
select(x+1,0);
x=getmin(node[root].ch[1]);
splay(x,root);
node[node[root].ch[1]].ch[0]=p;
node[p].f=x;
push_up(p);
push_up(node[root].ch[1]);
push_up(root);
}
void reverse(int l,int r)
{
select(l,0);
select(r+2,root);
node[node[node[root].ch[1]].ch[0]].col^=1;
}
int select(int k,int rt)
{
int tmp,t=root;
for(;;)
{
push_down(t);
int l=node[node[t].ch[0]].size;
if(k>l && k<=l+node[t].w) break;
if(k<=l)
t=node[t].ch[0];
else
k-=(l+node[t].w),t=node[t].ch[1];
}
splay(t,rt);
return t;
}
int getmin(int p)
{
push_down(p);
while(node[p].ch[0])
{
p=node[p].ch[0];
push_down(p);
}
return p;
}
int getmaxn(int p)
{
push_down(p);
while(node[p].ch[1])
{
p=node[p].ch[1];
push_down(p);
}
return p;
}
void push_down(int rt)
{
if(rt && node[rt].col)
{
swap(node[rt].ch[0],node[rt].ch[1]);
int l=node[rt].ch[0];
int r=node[rt].ch[1];
node[l].col^=1;
node[r].col^=1;
node[rt].col=0;
}
}
void push_up(int rt)
{
if(!rt)return;
int l=node[rt].ch[0];
int r=node[rt].ch[1];
int ret=node[rt].w;
if(l) ret+=node[l].size;
if(r) ret+=node[r].size;
node[rt].size=ret;
}
void del(int p)
{
if(!p) return;
del(node[p].ch[0]);
del(node[p].ch[1]);
delnode(p);
}
int build(int l,int r,int f)
{
if(l>r) return 0;
int m=(l+r)>>1;
int p=newnode(str[m]);
pos[m]=p;
node[p].f=f;
node[p].ch[0]=build(l,m-1,p);
node[p].ch[1]=build(m+1,r,p);
push_up(p);
return p;
}
};
spt s1;
int n,m,k;
void out(int p)
{
if(!p)
return;
else
{
s1.push_down(p);
out(node[p].ch[0]);
if(node[p].key[0]!='\0')
printf("%s\n",node[p].key);
out(node[p].ch[1]);
}
}
void prepare()
{
s1.clear();
s1.root=newnode("\0");
node[s1.root].ch[1]=newnode("\0");
node[node[s1.root].ch[1]].f=s1.root;
node[node[s1.root].ch[1]].ch[0]=s1.build(1,n,node[s1.root].ch[1]);
s1.push_up(node[s1.root].ch[1]);
s1.push_up(s1.root);
}
int main()
{
init();
while(~scanf("%d%d%d",&n,&m,&k))
{
for(int i=0;i<n;i++)
scanf("%s",str[i+1]);
prepare();
char ques[20];
for(int i=0;i<m;i++)
{
scanf("%s",ques);
if(ques[0]=='R')
{
int l,r;
l=1;
r=l+k-1;
r=r>n?n:r;
s1.reverse(l,r);
}
else
{
char ss[5];
int p=0,q=0;
while(ques[p++]!='(');
while(ques[p]!=')') ss[q++]=ques[p++];
ss[q]='\0';
s1.insertAt(0,ss);
n++;
}
}
out(s1.root);
s1.del(s1.root);
}
return 0;
}