题目描述
在桌子上有一堆书N本。可以在这堆书上进行如下两种操作:
1.在这堆书的顶端添加一本新书,其操作为ADD(S),S是书名;
2.把最上面的k本书的放置顺序颠倒。例如k=3,假设前三本书依次是《呐喊》,《彷徨》《哈里.波特》,进行此操作后顺序从上到下就变成了《哈里.波特》《彷徨》《呐喊》。若这堆书不足k本,就把整堆书全部翻转过来。其操作为ROTATE。任一时刻书的总数不会超过1000000。所有的书名为长度不超过3的由大写字母组成的字符串。书名有可能重复,但仍表示不同的书。
题目大意
加点,翻转,询问最后的结果
数据范围
数据范围
样例输入
2 3 2
A
B
ADD(C)
ROTATE
ADD(D)
样例输出
D
A
C
B
解题思路
Splay暴力维护。
代码
#include <bits/stdc++.h>
#define Maxn 2000005
using namespace std;
char ss[55];
int LLen;
inline void HashBack(int x) {
if(x>=729) {
ss[++LLen]=char(x/729+'A'-1);
HashBack(x%729);
return;
}
if(x>=27) {
ss[++LLen]=char(x/27+'A'-1);
HashBack(x%27);
return;
}
ss[++LLen]=char(x+'A'-1);
}
namespace IStream {
const int LLL=1<<15;
char buffer[LLL],*SSS,*TTT;
char Get_Char() {
if(SSS==TTT) {
TTT=(SSS=buffer)+fread(buffer,1,LLL,stdin);
if(SSS==TTT) return EOF;
}
return *SSS++;
} int Getint() {
char c;
int re=0,f=1;
for(c=Get_Char(); c<'0'||c>'9'; c=Get_Char())if(c=='-')f=-1;
while(c>='0'&&c<='9')re=(re<<1)+(re<<3)+(c-'0'),c=Get_Char();
return re*f;
}
bool Getstr() {
LLen=0;
char ch=Get_Char();
while(!isalpha(ch))ch=Get_Char();
if(ch=='R'){
Get_Char();
Get_Char();
Get_Char();
Get_Char();
Get_Char();
Get_Char();
return 1;
}
while(ch!='(')ch=Get_Char();
while((ch=Get_Char())!=')')ss[++LLen]=ch;
return 0;
}
void Get() {
LLen=0;
char ch=Get_Char();
while(!isalpha(ch))ch=Get_Char();
while(isalpha(ch))ss[++LLen]=ch,ch=Get_Char();
}
}
class OStream {
private:
static const int LLL=1<<20;
char staack[21];
int topp;
char buffer[LLL],*SSS;
public:
OStream() {
SSS=buffer;
} void Putint(int x,int flag) {
bool fl=false;
if(flag==1) staack[++topp]=' ';
if(flag==2) staack[++topp]='\n';
if(x<0) x=-x,fl=true;
if(!x) staack[++topp]='0';
while(x)staack[++topp]=x%10+'0',x/=10;
if(fl)staack[++topp]='-';
while(topp) {
if(SSS==buffer+LLL-1) {
fwrite(buffer,1,SSS-buffer,stdout);
SSS=buffer;
}*SSS++=staack[topp--];
}
} void Putstr(){
staack[++topp]='\n';
for(int i=LLen;i;i--)
staack[++topp]=ss[i];
while(topp){
if(SSS==buffer+LLL-1){
fwrite(buffer,1,SSS-buffer,stdout);
SSS=buffer;
}*SSS++=staack[topp--];
}
}~OStream() {
fwrite(buffer,1,SSS-buffer,stdout);
*SSS=0;
}
} os;
int a[Maxn];
struct splay {
int f[Maxn],son[Maxn][2],vl[Maxn],size[Maxn],lazy[Maxn],root,cnt;
inline void PushUp(int x) {
if(x)size[x]=size[son[x][0]]+size[son[x][1]]+1;
}
inline void PushDown(int x) {
if(lazy[x]) {
lazy[son[x][0]]^=1;
lazy[son[x][1]]^=1;
swap(son[x][0],son[x][1]);
lazy[x]=0;
}
}
inline void Rotate(int &x) {
int fa=f[x],gr=f[fa],s=son[fa][1]==x,sn=son[x][!s];
son[f[x]=gr][son[gr][1]==fa]=x;
son[f[fa]=x][!s]=fa;
son[f[sn]=fa][s]=sn;
PushUp(sn);
PushUp(fa);
PushUp(x);
}
inline void Splay(int x,int goal) {
if(x==goal)return;
while(f[x]!=goal) {
if(f[f[x]])PushDown(f[f[x]]);
if(f[x])PushDown(f[x]);
if(x)PushDown(x);
if(f[f[x]]!=goal&&(son[f[f[x]]][1]==f[x])==(son[f[x]][1]==x))Rotate(f[x]);
Rotate(x);
}
if(!goal)root=x;
}
inline int Select(int pos) {
if(!pos)return 0;
int p=root;
PushDown(p);
while(size[son[p][0]]+1!=pos) {
if(pos<=size[son[p][0]])p=son[p][0];
else pos-=size[son[p][0]]+1,p=son[p][1];
PushDown(p);
}
return p;
}
inline void Insert(int pos,int val) {
int u=Select(pos+1),v=Select(pos+2);
Splay(u,0);
Splay(v,u);
PushDown(u);
PushDown(v);
size[++cnt]=1;
vl[cnt]=val;
f[cnt]=v;
son[v][0]=cnt;
PushUp(v);
PushUp(u);
}
inline void Rev(int L,int r) {
int u=Select(L),v=Select(r+2);
Splay(u,0);
Splay(v,u);
lazy[son[v][0]]^=1;
}
inline void Build(int L,int r,int fa) {
int mid=(L+r)/2;
if(L>r)return;
if(L!=r)Build(L,mid-1,mid),Build(mid+1,r,mid);
vl[mid]=a[mid-1];
PushUp(mid);
f[mid]=fa;
son[fa][mid>=fa]=mid;
}
inline void Init(int &n) {
Build(1,n+2,0);
root=n+3>>1;
cnt=n+2;
}
void DEBUG(int x,int dep){
if(!x)return;
PushDown(x);
DEBUG(son[x][0],dep+1);
if(vl[x]){
LLen=0;
HashBack(vl[x]);
os.Putstr();
}
DEBUG(son[x][1],dep+1);
}
} Solver;
inline int Hash() {
if(LLen==3)return (ss[1]-'A'+1)*27*27+(ss[2]-'A'+1)*27+ss[3]-'A'+1;
if(LLen==2)return (ss[1]-'A'+1)*27+(ss[2]-'A'+1);
if(LLen==1)return (ss[1]-'A'+1);
}
int main() {
int n,m,k,N;
N=n=IStream::Getint();
m=IStream::Getint();
k=IStream::Getint();
for(int i=1; i<=n; i++) {
IStream::Get();
a[i]=Hash();
}
Solver.Init(n);
int L=0;
for(register int i=1;i<=m;i++){
bool ret=IStream::Getstr();
if(ret)L^=1;
else {
if(L){
Solver.Rev(1,min(n,k));
L=0;
}
Solver.Insert(0,Hash()),n++;
}
}
if(L)Solver.Rev(1,min(n,k));
Solver.DEBUG(Solver.root,0);
return 0;
}