P4567 [AHOI2006] 文本编辑器

题意

要维护一个字符串,带有一个光标,支持一下操作。

  • Move k:将光标移动到第 \(k\) 个字符之后,如果 \(k=0\),将光标移到文本第一个字符之前。
  • Insert n (换行) S:在光标后插入长度为 \(n\) 的字符串 \(S\),光标位置不变,\(n \ge 1\)
  • Delete n:删除光标后的 \(n\) 个字符,光标位置不变,\(n \ge 1\)
  • Rotate n:反转光标后的 \(n\) 个字符,光标位置不变,\(n \ge 1\)
  • Get:输出光标后的一个字符,光标位置不变。
  • Prev:光标前移一个字符。
  • Next:光标后移一个字符。

数据范围

  1. MOVE 操作不超过 \(5\times 10^4\) 个,INSERT, DELETEROTATE 操作作的总个数不超过 \(6\times 10^3\)GET 操作不超过 \(2\times 10^4\) 个,PREVNEXT 操作的总个数不超过 \(2\times 10^4\)
  2. 所有 INSERT 插入的字符数之和不超过 \(2M\)\(1M=2^{20}\))。
  3. DELETE 操作、ROTATE 操作和 GET 操作执行时光标后必然有足够的字符。MOVEPREVNEXT 操作不会把光标移动到非法位置。

思路

平衡树板子题,但是祂太难写了,所以需要向量树!

代码

用的是向量树,很短。

/*
Luogu P4567 [AHOI2006] 文本编辑器
2026-04-12
*/
#include<bits/stdc++.h>
using namespace std;
namespace IO{
    template<typename T>
    inline void read(T&x){
        x=0;char c=getchar();bool f=0;
        while(!isdigit(c)) c=='-'?f=1:0,c=getchar();
        while(isdigit(c)) x=x*10+c-'0',c=getchar();
        f?x=-x:0;
    }
    template<typename T>
    inline void write(T x){
        if(x==0){putchar('0');return ;}
        x<0?x=-x,putchar('-'):0;short st[50],top=0;
        while(x) st[++top]=x%10,x/=10;
        while(top) putchar(st[top--]+'0');
    }
    inline void read(char&c){c=getchar();while(isspace(c)) c=getchar();}
    inline void write(char c){putchar(c);}
    inline void read(string&s){s.clear();char c;read(c);while(!isspace(c)&&~c) s+=c,c=getchar();}
    inline void write(string s){for(int i=0,len=s.size();i<len;i++) putchar(s[i]);}
    template<typename T>inline void write(T*x){while(*x) putchar(*(x++));}
    template<typename T,typename...T2> inline void read(T&x,T2&...y){read(x),read(y...);}
    template<typename T,typename...T2> inline void write(const T x,const T2...y){write(x),putchar(' '),write(y...),sizeof...(y)==1?putchar('\n'):0;}
}using namespace IO;
vector<char>vt,ls;
int w;
signed main(){
    int n;read(n);
    for(int i=1;i<=n;i++){
        string op;read(op);
        if(op=="Move") read(w);
        if(op=="Insert"){
            int n;read(n);
            ls.resize(n);
            for(int i=0;i<n;i++) ls[i]=getchar();
            vt.insert(vt.begin()+w,ls.begin(),ls.end());
        }
        if(op=="Delete"){
            int n;read(n);
            vt.erase(vt.begin()+w,vt.begin()+w+n);
        }
        if(op=="Rotate"){
            int n;read(n);
            reverse(vt.begin()+w,vt.begin()+w+n);
        }
        if(op=="Get"){
            char ans=vt[w];
            if(ans=='\n') write("\n");
            else write(ans),write("\n");
        }
        if(op=="Prev") w--;
        if(op=="Next") w++;
    }
    return 0;
}
posted @ 2026-04-16 20:58  Link-Cut_Trees  阅读(5)  评论(0)    收藏  举报