一不小心又开启了每天昏迷24个小时的状态,脑子不清醒的时候就该去看动画片。
只需要记录光标的位置即可,剩下的就是Splay的经典操作了,不多说了,我只是为了测试模板。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define _INF 0x3f3f3f3f
#define Mod 9999991
using namespace std;
const int MAXN = 3001000;
struct N
{
//info
int son[2],pre;
//data
char data;
int mark;
int ls,rs,s;
} st[MAXN];
int Top;
char s[MAXN];
void Push_Down(int root)
{
if(st[root].mark == 1)
{
st[root].mark = 0;
if(st[root].son[0] != -1)
st[st[root].son[0]].mark ^= 1;
if(st[root].son[1] != -1)
st[st[root].son[1]].mark ^= 1;
int temp = st[root].ls;
st[root].ls = st[root].rs;
st[root].rs = temp;
temp = st[root].son[0];
st[root].son[0] = st[root].son[1];
st[root].son[1] = temp;
}
}
void Updata(int root)
{
st[root].ls = 0,st[root].rs = 0;
if(st[root].son[0] != -1)
{
st[root].ls = st[st[root].son[0]].s;
}
if(st[root].son[1] != -1)
{
st[root].rs = st[st[root].son[1]].s;
}
st[root].s = st[root].ls + st[root].rs + 1;
}
void Init(int &root,int s,int e,int pre,char *S)
{
if(s > e)
return ;
int mid = (s+e)>>1;
root = Top++;
st[root].son[0] = -1,st[root].son[1] = -1;
st[root].pre = pre;
st[root].data = S[mid];
st[root].mark = 0;
Init(st[root].son[0],s,mid-1,root,S);
Init(st[root].son[1],mid+1,e,root,S);
Updata(root);
}
void Rotate(int root,int dir)
{
st[st[root].pre].son[dir] = st[root].son[1^dir];
st[root].son[1^dir] = st[root].pre;
if(st[st[st[root].pre].pre].son[0] == st[root].pre)
st[st[st[root].pre].pre].son[0] = root;
else
st[st[st[root].pre].pre].son[1] = root;
int temp = st[root].pre;
st[root].pre = st[st[root].pre].pre;
st[temp].pre = root;
if(st[temp].son[dir] != -1)
st[st[temp].son[dir]].pre = temp;
Updata(temp);
Updata(root);
}
int Splay(int root,int goal)
{
while(st[root].pre != goal)
{
Rotate(root,(st[st[root].pre].son[0] == root ? 0 : 1));
}
return root;
}
int Search_Site(int root,int site)
{
do
{
Push_Down(root);
if(st[root].ls + 1 == site)
return root;
if(st[root].ls + 1 < site)
{
site = site - st[root].ls - 1;
root = st[root].son[1];
}
else
root = st[root].son[0];
}while(1);
}
void Insert(int &R,int site,int len,char *s)
{
R = Splay(Search_Site(R,site+1),0);
R = Splay(Search_Site(R,site),0);
int tr = -1;
Init(tr,1,len,st[R].son[1],s);
st[st[R].son[1]].son[0] = tr;
Updata(st[R].son[1]);
Updata(R);
}
void Delete(int &R,int site,int len)
{
R = Splay(Search_Site(R,site+len+1),0);
R = Splay(Search_Site(R,site),0);
st[st[R].son[1]].son[0] = -1;
Updata(st[R].son[1]);
Updata(R);
}
void Rotate(int &R,int site,int len)
{
R = Splay(Search_Site(R,site+len+1),0);
R = Splay(Search_Site(R,site),0);
st[st[st[R].son[1]].son[0]].mark ^= 1;
}
void Get(int &R,int site)
{
printf("%c\n",st[Search_Site(R,site+1)].data);
}
int main()
{
char S[5];
S[1] = '*',S[2] = '*',S[3] = '\n';
int n;
int root;
int len;
char order[10];
int site;
while(scanf("%d",&n) != EOF)
{
root = -1,Top = 1;
Init(root,1,2,0,S);
st[0].son[0] = root,st[0].son[1] = -1;
site = 1;
while(n--)
{
scanf("%s",order);
if(strcmp(order,"Insert") == 0)
{
scanf("%d%*c",&len);
gets(s+1);
Insert(root,site,len,s);
}
else if(strcmp(order,"Move") == 0)
{
scanf("%d",&len);
site = len+1;
}
else if(strcmp(order,"Delete") == 0)
{
scanf("%d",&len);
Delete(root,site,len);
}
else if(strcmp(order,"Rotate") == 0)
{
scanf("%d",&len);
Rotate(root,site,len);
}
else if(strcmp(order,"Get") == 0)
{
Get(root,site);
}
else if(strcmp(order,"Prev") == 0)
{
site--;
}
else if(strcmp(order,"Next") == 0)
{
site++;
}
}
}
return 0;
}