题解:
splay维护
只不过变成了字符串
代码:
#include<bits/stdc++.h> using namespace std; const int L=2000000+10,BS=3000 + 100,BN=3000 + 10; int Cur=0,head,tot; char str[L]; struct Block { int size,nxt; bool rev; char a[BS]; void Clear(){size=0;nxt=-1,rev=0;} }B[BN]; queue<int>q; int NewNode() { int t=q.front();q.pop(); B[t].Clear(); return t; } void Pre() { while (q.size()!=0)q.pop(); for (int i=0;i<BN;i++)q.push(i); head=NewNode(); } void Find(int &idx,int &cur) { while(idx!=-1&&cur>B[idx].size)cur-=B[idx].size,idx=B[idx].nxt; } void Pushdown(int idx) { if (B[idx].rev) { reverse(B[idx].a,B[idx].a+B[idx].size); B[idx].rev=0; } } void Split(int idx,int cur) { if(idx==-1||cur==B[idx].size)return; Pushdown(idx); int tot=NewNode(); memcpy(B[tot].a,B[idx].a+cur,sizeof(char)*(B[idx].size-cur) ); B[tot].size=B[idx].size-cur; B[idx].size=cur; B[tot].nxt=B[idx].nxt; B[idx].nxt=tot; } void Delet(int idx){q.push(idx);} void Merge(int idx) { for (int i=idx;i!=-1;i=B[i].nxt) for (int j=B[i].nxt;j!=-1;j=B[j].nxt) { if (B[i].size+B[j].size<=BS) { Pushdown(i); Pushdown(j); memcpy(B[i].a+B[i].size,B[j].a,sizeof(char) * B[j].size); B[i].size+=B[j].size;B[i].nxt=B[j].nxt; Delet(j); } else break; } } void Insert(int cur,int x,char *str) { int idx=head; Find(idx,cur); Split(idx,cur); int i=0; while(i<x) { int Limit=min(BS,x-i); int tot=NewNode(); memcpy(B[tot].a,str+i,sizeof(char) * Limit); B[tot].size=Limit; B[tot].nxt=B[idx].nxt; B[idx].nxt=tot; idx=B[idx].nxt; i+=Limit; } Merge(head); } void Print(int cur) { int idx=head; Find(idx,cur); if(cur==B[idx].size) idx=B[idx].nxt,cur=0; Pushdown(idx); printf("%c\n",B[idx].a[cur]); } void Rever(int l,int r) { int idx=head; Find(idx,l); Split(idx,l); int Start=idx,StartNxt=B[idx].nxt; idx=head; Find(idx,r); Split(idx,r); int EndNxt=B[idx].nxt,Tmp[BN],cnt=0; for (int i=StartNxt;i!=EndNxt;i=B[i].nxt)B[i].rev^=1,Tmp[++cnt]=i; Tmp[++cnt]=Start;Tmp[0]=EndNxt; for (int i=cnt;i>=1;i--)B[Tmp[i]].nxt=Tmp[i-1]; Merge(head); } void Dele(int l,int r) { int idx=head; Find(idx,l); Split(idx,l); int Start=idx,StartNxt=B[idx].nxt; idx=head; Find(idx,r); Split(idx,r); int EndNxt=B[idx].nxt; for (int i=StartNxt;i!=EndNxt;i=B[i].nxt)Delet(i); B[Start].nxt=EndNxt; Merge(head); } int main() { int N; scanf("%d",&N); char opt[20]; Pre(); while(N--) { scanf("%s",opt); if (opt[0]=='M') scanf("%d",&Cur); else if (opt[0]=='I') { int len; scanf("%d",&len); int i=0; while(i<len){char ch=getchar();if (ch>=32&&ch<=126)str[i++]=ch;} str[i++]='\0'; Insert(Cur,len,str); } else if(opt[0]=='D') { int x; scanf("%d",&x); Dele(Cur,Cur+x); } else if(opt[0]=='R') { int x; scanf("%d",&x); Rever(Cur,x+Cur); } else if(opt[0]=='G')Print(Cur); else if(opt[0]=='P')Cur--; else if(opt[0]=='N')Cur++; } return 0; }