bzoj1269 文本编辑器

Description   这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器。你能帮助他吗?
  为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或多个字符构成的序列。这些字符的ASCII码在闭区间[32,
126]内,也就是说,这些字符均为可见字符或空格。
  光标:在一段文本中用于指示位置的标记,可以位于文本的第一个字符之前,文本的最后一个字符之后或文本的某两个相邻字符之间。
  文本编辑器:为一个可以对一段文本和该文本中的一个光标进行如下七条操作的程序。如果这段文本为空,我们就说这个文本编辑器是空的。   
任务:编写一个程序:   建立一个空的文本编辑器。   从输入文件中读入一些操作指令并执行。
  对所有执行过的GET操作,将指定的内容写入输出文件。 Input   输入文件中第一行是指令条数N,以下是需要执行的N个操作。
  除了回车符之外,输入文件的所有字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。 Output
  输出文件editor.out的每行依次对应输入文件中每条GET指令的输出,不得有任何多余的字符。

平衡树模板题。

#include<cstdio>
#include<cstring>
struct node
{
    int f,k[2],size;
    bool b;
    char c;
}t[2100000];
char s[2100000];
int p=1,l,size=2,root=1;
void up(int k)
{
    t[k].size=t[t[k].k[0]].size+t[t[k].k[1]].size+1;
}
void down(int k)
{
    if (t[k].b)
    {
        int x=t[k].k[0];
        t[k].k[0]=t[k].k[1];
        t[k].k[1]=x;
        if (t[k].k[0]) t[t[k].k[0]].b=!t[t[k].k[0]].b;
        if (t[k].k[1]) t[t[k].k[1]].b=!t[t[k].k[1]].b;
        t[k].b=0;
    }
}
int find(int k,int x)
{
    down(k);
    if (t[t[k].k[0]].size>=x) return find(t[k].k[0],x);
    if (t[t[k].k[0]].size+1==x) return k;
    return find(t[k].k[1],x-t[t[k].k[0]].size-1);
}
void rot(int k,int b)
{
    down(k);
    int x=t[k].f;
    int y=t[k].k[b];
    down(y);
    int z=t[y].k[!b];
    down(z);
    if (x) t[x].k[t[x].k[1]==k]=y;
    t[y].f=x;
    t[y].k[!b]=k;
    t[k].f=y;
    t[k].k[b]=z;
    if (z) t[z].f=k;
    up(k);
    up(y);
} 
void splay(int k)
{
    down(k);
    int x,y;
    while (t[k].f)
    {
        x=t[k].f;
        if (!t[x].f)
        {
            rot(x,t[x].k[1]==k);
            root=k;
            return;
        }
        y=t[x].f;
        if ((t[y].k[1]==x)==(t[x].k[1]==k))
          rot(y,t[y].k[1]==x),rot(x,t[x].k[1]==k);
        else
          rot(x,t[x].k[1]==k),rot(y,t[y].k[1]==k);
    }
    root=k;
}
int build(int l,int r)
{
    if (l>r)
      return 0;
    int mid=(l+r)/2;
    int x=build(l,mid-1);
    int y=build(mid+1,r);
    ++size;
    if (x) t[x].f=size;
    if (y) t[y].f=size;
    t[size].k[0]=x;
    t[size].k[1]=y;
    t[size].c=s[mid];
    up(size);
    return size;
}
void ins()
{
    int x=find(root,p);
    splay(x);
    int y=build(1,l),z=t[x].k[1];
    t[x].k[1]=y,t[y].f=x,up(x);
    int w=y;
    down(w);
    while (t[w].k[1]) w=t[w].k[1],down(w);
    splay(w);
    t[w].k[1]=z;
    if(z) t[z].f=w;
    up(w);
}
void del()
{
    int x=find(root,p+l);
    splay(x);
    int y=t[x].k[1];
    t[x].k[1]=0;
    up(x);
    int z=find(root,p);
    splay(z);
    t[z].k[1]=y;
    t[y].f=z;
    up(z);
}
void opp()
{
    int x,y;
    x=find(root,p);
    splay(x);
    y=find(root,p+l+1);
    t[t[x].k[1]].f=0;
    splay(y);
    t[t[y].k[0]].b=!t[t[y].k[0]].b;
    root=x;
    t[x].k[1]=y;
    t[y].f=x;
    up(y);
    up(x);
}
void prt()
{
    int x=find(root,p+1);
    splay(x);
    printf("%c\n",t[x].c);
}
int main()
{
    int n,i,j;
    char c[30];
    scanf("%d",&n);
    t[1].c=t[2].c=' ';
    t[1].size=2;
    t[2].size=1;
    t[1].k[1]=2;
    t[2].f=1;
    while (n--)
    {
        scanf("%s",c+1);
        if (c[1]=='M') scanf("%d",&p),p++;
        if (c[1]=='I') scanf("%d%*c",&l),gets(s+1),ins();
        if (c[1]=='D') scanf("%d",&l),del();
        if (c[1]=='R') scanf("%d",&l),opp();
        if (c[1]=='G') prt();
        if (c[1]=='P') p--;
        if (c[1]=='N') p++;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值