Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description
You are in charge of data in a company, so you are called "Data Handler". Different from the data in computer, the data you have are really in huge volume, and each data contains only one integer. All the data are placed in a line from left to right. There are two "hand" to handle the data, call hand "L" and hand "R". Every hand is between two adjacent data or at the end of the data line.
In one day, the company gives you many commands to handle these data, so you should finish them one by one. At the beginning, there are N data, and hand "L" and "R" are in some positions. Each command is one the following formats:
(1)MoveLeft L/R: it means that you should move the hand "L"/"R" left one data unit;
(2)MoveRight L/R: it means that you should move the hand "L"/"R" right one data unit;
(3)Insert L X: it means that you should insert the data that contains X at the right of the hand "L";
(4)Insert R X: it means that you should insert the data that contains X at the left of the hand "R";
(5)Delete L: it means that you should delete the one data at the right of the hand "L";
(6)Delete R: it means that you should delete the one data at the left of the hand "R";
(7)Reverse: it means that you should reverse all the data between hand "L" and hand "R".
After finish all the commands, you should record all the data from left to right. So please do it.
In one day, the company gives you many commands to handle these data, so you should finish them one by one. At the beginning, there are N data, and hand "L" and "R" are in some positions. Each command is one the following formats:
(1)MoveLeft L/R: it means that you should move the hand "L"/"R" left one data unit;
![](https://i-blog.csdnimg.cn/blog_migrate/ff75698c2dcbb2ad7e85123bf259266c.jpeg)
(2)MoveRight L/R: it means that you should move the hand "L"/"R" right one data unit;
![](https://i-blog.csdnimg.cn/blog_migrate/90d8aca97f312dd26b5c8e699f7cc27f.jpeg)
(3)Insert L X: it means that you should insert the data that contains X at the right of the hand "L";
![](https://i-blog.csdnimg.cn/blog_migrate/c8ad139841403ac427c05eea274f6cf1.jpeg)
(4)Insert R X: it means that you should insert the data that contains X at the left of the hand "R";
![](https://i-blog.csdnimg.cn/blog_migrate/3db93463f6fb0c77e347f645b85ad317.jpeg)
(5)Delete L: it means that you should delete the one data at the right of the hand "L";
![](https://i-blog.csdnimg.cn/blog_migrate/1a463698b0ef187e9728eadfa867a2b4.jpeg)
(6)Delete R: it means that you should delete the one data at the left of the hand "R";
![](https://i-blog.csdnimg.cn/blog_migrate/38c55377807a098320348d1c0b40193b.jpeg)
(7)Reverse: it means that you should reverse all the data between hand "L" and hand "R".
![](https://i-blog.csdnimg.cn/blog_migrate/ec31adeaa01535c38cc168a1436b6909.jpeg)
After finish all the commands, you should record all the data from left to right. So please do it.
Input
The first line contains an integer T(1<=T<=10), the number of test cases.
Then T test cases follow. For each test case, the first line contains an integer N(1<=N<=500000), the number of data at the beginning. The second line contains N integers, means the integer in each data, from left to right. The third line contains two integers L and R (1<=L<=R<=N), the positions of hand "L" and hand "R". It means that hand "L" is at the left of the L-th data and hand "R" is at the right of the R-th data. The fourth line contains one integer M(1<=M<=500000), the number of commands. Then M lines follow, each line contains a command in the above format. All the integers in the data will in range [-10000,10000].
It is guaranteed that there are always some data between hand "L" and "R", and if the hand is at the left/right end of the data line, it will not receive the command MoveLeft/MoveRight.
Because of large input, please use scanf instead of cin.
Then T test cases follow. For each test case, the first line contains an integer N(1<=N<=500000), the number of data at the beginning. The second line contains N integers, means the integer in each data, from left to right. The third line contains two integers L and R (1<=L<=R<=N), the positions of hand "L" and hand "R". It means that hand "L" is at the left of the L-th data and hand "R" is at the right of the R-th data. The fourth line contains one integer M(1<=M<=500000), the number of commands. Then M lines follow, each line contains a command in the above format. All the integers in the data will in range [-10000,10000].
It is guaranteed that there are always some data between hand "L" and "R", and if the hand is at the left/right end of the data line, it will not receive the command MoveLeft/MoveRight.
Because of large input, please use scanf instead of cin.
Output
For each test case, output the integers in the data from left to right in one line, separated in a single space.
Because of large output, please use printf instead of cout.
Because of large output, please use printf instead of cout.
Sample Input
2 5 1 2 3 4 5 1 5 5 MoveLeft R Insert R 6 Reverse Delete R Insert L 7 5 6536 5207 2609 6604 -4046 1 3 5 Delete L Insert R -9221 Reverse Delete L MoveRight L
Sample Output
7 6 4 3 2 5 2609 5207 6604 -4046
题意:给你一段数字,一个左指针和一个右指针,然后有七种操作,操作n次后,从左至右依次输出变化后的数字串。
七种操作都非常简单易懂,但是数据很大,如果暴力模拟绝对超时。
这里我把这一串数字串拆分成了三部分,在左指针左边的作为一个栈,右指针右边的作为一个栈(因为对这两部分的操作只有从一边进,从这一边出)
两个指针之间的做成一个双向链表,方便拆分和删除,以及最后的输出遍历。
难点在于颠倒操作,但这样拆成三部分之后,每次不用真正颠倒,只用直接将一个标记flag++就好了,奇数时代表串是反的,偶数时代表串是正的,然后在进行其它操作时判断flag的奇偶然后分别操作就好了。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <algorithm>
#include <vector>
#include <map>
#define PI acos(-1.0)
#define M 1000005 //10^6
#define eps 1e-8
#define LL long long
#define moo 1000000007
#define INF -999999999
#define LL long long
using namespace std;
struct aaa
{
int val;
int le;
int ri;
}aa[M]; //双向链表
int stle[M];//左栈
int stri[M];//右栈
int b[M]; //初始读入数组
char a[10];
char d[10];
int judge()
{
if(strcmp(a,"MoveLeft")==0)
return 1;
if(strcmp(a,"MoveRight")==0)
return 2;
if(strcmp(a,"Insert")==0)
return 3;
if(strcmp(a,"Delete")==0)
return 4;
if(strcmp(a,"Reverse")==0)
return 5;
}
int main()
{
int m,n,T;
while(scanf("%d",&T)!=EOF)
{
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
}
int lee,rii;
scanf("%d%d",&lee,&rii);
int hele=0,heri=0;
for(int i=1;i<lee;i++)
{
hele++;
stle[hele]=b[i];
}
for(int i=n;i>rii;i--)
{
heri++;
stri[heri]=b[i];
}
int now=rii-lee;
for(int i=lee;i<=rii;i++)
{
aa[i-lee].le=i-lee-1;
aa[i-lee].ri=(i==rii?-1:i-lee+1);
aa[i-lee].val=b[i];
}
rii=rii-lee;
lee=0;
//以上是把三部分分别储存好的操作。
scanf("%d",&m);
int flag=0;
while(m--)
{
scanf("%s",a);
int tt=judge();
if(tt==5)
{
flag++;
continue;
}
if(tt==1)
{
scanf("%s",d);
if(strcmp(d,"L")==0)
{
aa[++now].val=stle[hele--];
if(flag%2==0)
{
aa[now].le=-1;
aa[lee].le=now;
aa[now].ri=lee;
lee=now;
}
else
{
aa[now].ri=-1;
aa[rii].ri=now;
aa[now].le=rii;
rii=now;
}
}
else
{
if(flag%2==0)
{
stri[++heri]=aa[rii].val;
aa[aa[rii].le].ri=-1;
rii=aa[rii].le;
}
else
{
stri[++heri]=aa[lee].val;
aa[aa[lee].ri].le=-1;
lee=aa[lee].ri;
}
}
continue;
}
if(tt==2)
{
scanf("%s",d);
if(strcmp(d,"R")==0)
{
aa[++now].val=stri[heri--];
if(flag%2==0)
{
aa[now].ri=-1;
aa[rii].ri=now;
aa[now].le=rii;
rii=now;
}
else
{
aa[now].le=-1;
aa[lee].le=now;
aa[now].ri=lee;
lee=now;
}
}
else
{
if(flag%2==0)
{
stle[++hele]=aa[lee].val;
aa[aa[lee].ri].le=-1;
lee=aa[lee].ri;
}
else
{
stle[++hele]=aa[rii].val;
aa[aa[rii].le].ri=-1;
rii=aa[rii].le;
}
}
continue;
}
if(tt==3)
{
scanf("%s",d);
int kkk;
scanf("%d",&kkk);
now++;
aa[now].val=kkk;
if(strcmp(d,"L")==0)
{
if(flag%2==0)
{
aa[now].ri=lee;
aa[now].le=-1;
aa[lee].le=now;
lee=now;
}
else
{
aa[now].le=rii;
aa[now].ri=-1;
aa[rii].ri=now;
rii=now;
}
}
else
{
if(flag%2==0)
{
aa[now].le=rii;
aa[now].ri=-1;
aa[rii].ri=now;
rii=now;
}
else
{
aa[now].ri=lee;
aa[now].le=-1;
aa[lee].le=now;
lee=now;
}
}
continue;
}
if(tt==4)
{
scanf("%s",d);
if(strcmp(d,"L")==0)
{
if(flag%2==0)
{
lee=aa[lee].ri;
aa[lee].le=-1;
}
else
{
rii=aa[rii].le;
aa[rii].ri=-1;
}
}
else
{
if(flag%2==0)
{
rii=aa[rii].le;
aa[rii].ri=-1;
}
else
{
lee=aa[lee].ri;
aa[lee].le=-1;
}
}
}
}
//以上是分别处理7种不同操作
//下面是输出部分,因为flag的原因,在输出链表部分的时候也得判断正反
int fuck=0;
for(int i=1;i<=hele;i++)
{
if(fuck==0)
{
cout<<stle[i];
fuck=1;
}
else
cout<<" "<<stle[i];
}
if(flag%2==0)
{
while(lee!=-1)
{
if(fuck==0)
{
cout<<aa[lee].val;
fuck=1;
}
else
cout<<" "<<aa[lee].val;
lee=aa[lee].ri;
}
}
else
{
while(rii!=-1)
{
if(fuck==0)
{
cout<<aa[rii].val;
fuck=1;
}
else
cout<<" "<<aa[rii].val;
rii=aa[rii].le;
}
}
for(int i=heri;i>0;i--)
{
if(fuck==0)
{
cout<<stri[i];
fuck=1;
}
else
cout<<" "<<stri[i];
}
cout<<endl;
}
}
}