[NOI2003]Editor & [AHOI2006]文本编辑器editor BZOJ1507&BZOJ1269

分析:

Splay区间操作裸题,维护出区间信息,按照要求模拟,注意读入格式,并且考虑内存回收(开不下)

附上代码:

#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <map>
using namespace std;
#define N 2097200
#define ls ch[rt][0]
#define rs ch[rt][1]
#define get(rt) (ch[f[rt]][0]!=rt)
int ch[N][2],f[N],cnt,siz[N],val[N],S[N],top,rot,pos,size,rev[N];char op[20],s[N];
void clear(int rt)
{
    rev[rt]=ch[rt][0]=ch[rt][1]=f[rt]=siz[rt]=val[rt]=0;
}
void PushUp(int rt)
{
    if(rt)siz[rt]=siz[ls]+siz[rs]+1;
}
void PushDown(int rt)
{
    if(rev[rt])
    {
        if(ls)rev[ls]^=1,swap(ch[ls][0],ch[ls][1]);
        if(rs)rev[rs]^=1,swap(ch[rs][0],ch[rs][1]);
        rev[rt]=0;
    }
}
int new_node()
{
    int rt;
    if(top)rt=S[--top];
    else rt=++cnt;
    clear(rt);
    return rt;
}
void rotate(int rt)
{
    int x=f[rt],y=f[x],k=get(rt);
    if(y)ch[y][ch[y][0]!=x]=rt;
    ch[x][k]=ch[rt][!k];f[ch[x][k]]=x;
    ch[rt][!k]=x;f[x]=rt;f[rt]=y;
    if(rot==x)rot=rt;PushUp(x);PushUp(rt);
}
void Splay(int rt,int y)
{
    for(int fa;(fa=f[rt])!=y;rotate(rt))
        if(f[fa]!=y)
            rotate((get(fa)==get(rt))?fa:rt);
}
void build(int fa,int l,int r,bool flg)
{
    if(l>r)return ;
    int m=(l+r)>>1,rt=new_node();
    val[rt]=s[m];ch[fa][flg]=rt;f[rt]=fa;
    build(rt,l,m-1,0);build(rt,m+1,r,1);PushUp(rt);
}
int find(int x)
{
    int rt=rot;
    while(1)
    {
        PushDown(rt);
        if(siz[ls]>=x)rt=ls;
        else
        {
            x-=siz[ls]+1;
            if(!x)return rt;
            rt=rs;
        }
    }
}
void rec(int rt)
{
    if(!rt)return ;
    if(ls)rec(ls);ls=0;if(rs)rec(rs);rs=0;
    clear(rt);S[top++]=rt;
}
void insert(int len)
{
    int x=find(pos),rt=find(pos+1);Splay(x,0);Splay(rt,rot);
    build(rt,1,len,0);PushUp(rt);PushUp(x);
}
void del(int len)
{
    int x=find(pos),rt=find(pos+len+1);Splay(x,0);Splay(rt,rot);
    rec(ls);ls=0;PushUp(rt);PushUp(x);
}
void reverse(int len)
{
    int x=find(pos),y=find(pos+len+1);Splay(x,0);Splay(y,rot);
    int rt=ch[y][0];swap(ls,rs);rev[rt]^=1;
}
int main()
{
    int Q;
    scanf("%d",&Q);
    siz[1]=2,siz[2]=1,ch[1][1]=2,f[2]=1,rot=pos=1,size=cnt=2;
    while(Q--)
    {
        int x;
        scanf("%s",op);
        if(op[0]=='M')scanf("%d",&x),pos=x+1;
        else if(op[0]=='I')
        {
            scanf("%d",&x);
            for(int i=1;i<=x;i++)
            {
                s[i]=getchar();
                while(s[i]>126||s[i]<32)s[i]=getchar();
            }
            s[x+1]='\0';
            //printf("%s",s+1);
            insert(x);size+=x;
        }else if(op[0]=='D')
        {
            scanf("%d",&x);
            if(x+pos+1>size)x=size-pos-1;
            del(x);size-=x;
        }else if(op[0]=='N')pos+=(pos!=size);
        else if(op[0]=='P')pos-=(pos>0);
        else if(op[0]=='G')
        {
            int y=find(pos),rt=find(pos+2);
            Splay(y,0);Splay(rt,rot);
            printf("%c\n",val[ls]);
        }else
        {
            scanf("%d",&x);
            if(x+pos+1>size)x=size-pos-1;
            reverse(x);
        }
    }
    return 0;
}

  

posted @ 2018-06-06 11:18  Winniechen  阅读(162)  评论(0编辑  收藏  举报