一不小心又开启了每天昏迷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; }
[AHOI2006]文本编辑器editor
时间: 2024-10-21 02:23:28