题解:

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;
}

 

posted on 2018-01-03 17:59  宣毅鸣  阅读(124)  评论(0编辑  收藏  举报