BZOJ-1269||1507文本编辑器editor

[文章目录]

Description

这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器。你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:

两道题差不多,就一起写了。RE了n遍,原因是数组开小了,2M QAQ...

说实话没什么难度,不过自己把zig与zag合并成了一个rotate,然后,旋转的代码就短了辣么多。开心。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int m,n,now;
char st[1000],a[3001000],ch;
struct node
{
    node *fa,*c[2];
    bool tur;
    char val;
    int size;
    node();
    void reverse();
    void push_up();
    void push_down();
}*null=new node(),*root=new node();

node :: node()
{
    fa=c[0]=c[1]=null;
    size=null?1:0;
    val=1; tur=false;
}
void node :: reverse()
{
    swap(c[0],c[1]);
    tur^=1;
}
void node :: push_up()
{
    size=c[0]->size+c[1]->size+1;
}
void node :: push_down()
{
    if(tur)
    {
        if(c[0]!=null) c[0]->reverse();
        if(c[1]!=null) c[1]->reverse();
        tur=0;
    }
}
node *build(int l,int r)
{
    if(l>r)return null;
    int mid=l+r>>1;
    node *re=new node(); re->val=a[mid];
    re->c[0]=build(l,mid-1); re->c[1]=build(mid+1,r);
    re->c[0]->fa=re;re->c[1]->fa=re;
    re->push_up();
    return re;
}
void initialize()
{
    root=new node();
    root->c[1]=new node();root->c[1]->fa=root;
}
void Free(node *x)
{
    if(x==null) return ;
    Free(x->c[0]);
    Free(x->c[1]);
    free(x);
}
void rotate(node *x)
{
    node *y=x->fa;int l=(x!=y->c[0]),r=l^1;
    y->c[l]=x->c[r];x->c[r]->fa=y;
    x->c[r]=y; x->fa=y->fa;
    if(y==y->fa->c[r]) y->fa->c[r]=x;
    else y->fa->c[l]=x;
    y->fa=x; y->push_up();x->push_up();
    if(root==y) root=x;
}
void splay(node *x,node *tar)
{
    while(x!=tar)
    {
        node *y=x->fa,*z=y->fa;
        if(y==tar) break;
        if(z==tar) {rotate(x);break;}
        if((y!=z->c[0])^(x==y->c[0])) rotate(y);
        else rotate(x);
        rotate(x);
    }
}
void find(node *x,int y,node *z)
{
    while(1)
    {
        x->push_down();
        int tmp=x->c[0]->size;
        if(y<=tmp) x=x->c[0];
        else
        {
            y-=tmp;if(y==1) break;y--;
            x=x->c[1];
        }
    }
    splay(x,z);
}
void dfs(node *x)
{
    if(x==null) return ;
    x->push_down();
    dfs(x->c[0]);
    printf("%c",x->val);
    dfs(x->c[1]);
}
int main()
{
    scanf("%d",&m);
    initialize();
    //dfs(root);
    //puts("");
    while(m--)
    {
        scanf("%s",st);
        switch(st[0])
        {
            case 'I':
            {
                int len;
                scanf("%d",&len);
                find(root,now+1,null);
                find(root,now+2,root);
                ch=getchar();
                while(ch<32||ch>126) ch=getchar();
                a[1]=ch;
                for(int i=2;i<=len;i++) a[i]=getchar();
                root->c[1]->c[0]=build(1,len);
                root->c[1]->c[0]->fa=root->c[1];
                root->c[1]->push_up();
                root->push_up();
                break;
            }
            case 'M':
            {
                scanf("%d",&n);
                now=n;
                break;
            }
            case 'D':
            {
                scanf("%d",&n);
                find(root,now+1,null);
                find(root,now+n+2,root);
                node *tmp=root->c[1]->c[0];
                root->c[1]->c[0]=null;
                root->c[1]->push_up();
                root->push_up();
                Free(tmp);
                break;
            }
            case 'R':
            {
                scanf("%d",&n);
                find(root,now+1,null);
                find(root,now+n+2,root);
                root->c[1]->c[0]->reverse();
                root->c[1]->push_up();
                root->push_up();
                break;
            }
            case 'G':
            {
                find(root,now+1,null);
                find(root,now+3,root);
                printf("%c\n",root->c[1]->c[0]->val);
                break;
            }
            case 'P':now--;break;
            case 'N':now++;break;
        }
        //printf("%d\n",now);
        //dfs(root);
        //puts("");
    }
    return 0;
}
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int m,n,now;
char st[1000],a[3001000],ch;
struct node
{
    node *fa,*c[2];
    char val;
    int size;
    node();
    void push_up();
}*null=new node(),*root;

node :: node()
{
    fa=c[0]=c[1]=null;
    size=null?1:0;
    val=1;
}
void node :: push_up()
{
    size=c[0]->size+c[1]->size+1;
}
node* build(int l,int r)
{
    if(l>r)return null;
    int mid=l+r>>1;
    node *re=new node(); re->val=a[mid];
    re->c[0]=build(l,mid-1); re->c[1]=build(mid+1,r);
    re->c[0]->fa=re; re->c[1]->fa=re;
    re->push_up();
    return re;
}
void initialize()
{
    root=new node();
    root->c[1]=new node();
    root->c[1]->fa=root;
    root->c[1]->push_up();root->push_up();
}
void Free(node *x)
{
    if(x==null) return ;
    Free(x->c[0]);
    Free(x->c[1]);
    free(x);
}
void rotate(node *x)
{
    node *y=x->fa;int l=(x!=y->c[0]),r=l^1;
    y->c[l]=x->c[r];x->c[r]->fa=y;
    x->c[r]=y; x->fa=y->fa;
    if(y==y->fa->c[r]) y->fa->c[r]=x;
    else if(y==y->fa->c[l]) y->fa->c[l]=x;
    y->fa=x; y->push_up();x->push_up();
    if(y==root) root=x;
}
void splay(node *x,node *tar)
{
    while(x!=tar)
    {
        node *y=x->fa,*z=y->fa;
        if(y==tar) break;
        if(z==tar) {rotate(x);break;}
        if((y==z->c[0])^(x==y->c[0])==0) rotate(y);
        else rotate(x);
        rotate(x);
    }
}
void find(node *x,int y,node *z)
{
    while(1)
    {
        int tmp=x->c[0]->size;
        if(y<=tmp) x=x->c[0];
        else
        {
            y-=(tmp+1);
            if(!y) break;
            x=x->c[1];
        }
    }
    splay(x,z);
}

void rd(int x)
{
    int cnt=1;char ch;
    while(cnt<=x)
    {
        ch=getchar();
        if(ch!='\n') 
            a[cnt]=ch,cnt++;
    }
}
void dfs(node *x)
{
    if(x==null) return ;
    dfs(x->c[0]);
    printf("%c",x->val);
    dfs(x->c[1]);
}
int main()
{
    scanf("%d",&m);
    initialize();
    while(m--)
    {
        scanf("%s",st);
        switch(st[0])
        {
            case 'I':
            {
                int len; scanf("%d",&len); rd(len);
                find(root,now+1,null);
                find(root,now+2,root);
                root->c[1]->c[0]=build(1,len);
                root->c[1]->c[0]->fa=root->c[1];
                root->c[1]->push_up();
                root->push_up();
                break;
            }
            case 'M':scanf("%d",&now);break;
            case 'D':
            {
                scanf("%d",&n);
                find(root,now+1,null);
                find(root,now+n+2,root);
                node *tmp=root->c[1]->c[0];
                root->c[1]->c[0]=null;
                root->c[1]->push_up();
                root->push_up();
                Free(tmp);
                break;
            }
            case 'G':
            {
                scanf("%d",&n);
                find(root,now+1,null);
                find(root,now+n+2,root);
                dfs(root->c[1]->c[0]);
                puts("");
                break;
            }
            case 'P':now--;break;
            case 'N':now++;break;
        }
    }
    return 0;
}

 

发表评论

邮箱地址不会被公开。 必填项已用*标注