bzoj1507: [NOI2003]Editor

来源:互联网 发布:上海公积金算法 编辑:程序博客网 时间:2024/09/21 08:15

平衡树裸题。光标位置直接修改就行,然后就区间插入删除,直接splay就行了。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int read(){    char ch=getchar();int f=0,x=1;    while(ch<'0'||ch>'9'){if(ch=='-') x=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){f=(f<<1)+(f<<3)+ch-'0';ch=getchar();}    return f*x;}int n,m,sz,rt,pos,cnt;int fa[3000005],ch[3000005][2],id[3000005];int size[3000005];char w[3000005];char op[15];void pushup(int x){    size[x]=1+size[ch[x][0]]+size[ch[x][1]];}void rotate(int x,int &k){    int y=fa[x],z=fa[y],l,r;    if(ch[y][0]==x) l=0;else l=1;r=l^1;    if(y==k) k=x;    else    {        if(ch[z][0]==y) ch[z][0]=x;        else ch[z][1]=x;    }    fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;    ch[y][l]=ch[x][r];ch[x][r]=y;    pushup(y);pushup(x);}void splay(int x,int &k){    while(x!=k)    {        int y=fa[x],z=fa[y];        if(y!=k)        {            if(ch[z][0]==y^ch[y][0]==x) rotate(x,k);            else rotate(y,k);        }        rotate(x,k);    }}int getmin(int x){    while(ch[x][0]) x=ch[x][0];    return x;}int kth(int x,int k){    int temp=size[ch[x][0]];    if(temp+1==k) return x;    if(k<=temp) return kth(ch[x][0],k);    return kth(ch[x][1],k-temp-1);}void build(int &x,int fa1,int l,int r,char *s){    if(l>r) return;    int mid=l+r>>1;    x=++sz;    ch[x][0]=ch[x][1]=size[x]=0;    fa[x]=fa1;    w[x]=s[mid];    build(ch[x][0],x,l,mid-1,s);    build(ch[x][1],x,mid+1,r,s);    pushup(x);}void insert(char *s,int l){    int x=kth(rt,pos);    splay(x,rt);    x=getmin(ch[rt][1]);    splay(x,ch[rt][1]);    build(ch[x][0],x,0,l-1,s);}char s[3000005];void out(int x,int k){    if(!ch[x][0]&&!ch[x][1])    {        cnt++;        if(cnt>k) return;        printf("%c",w[x]);        return;    }    if(ch[x][0]) out(ch[x][0],k);    cnt++;    if(cnt>k) return;    printf("%c",w[x]);    if(ch[x][1]) out(ch[x][1],k);}void del(int k){    //cout<<k<<" ";    int x=kth(rt,pos);    splay(x,rt);    x=kth(rt,pos+k+1);    splay(x,ch[rt][1]);    fa[ch[x][0]]=0;    ch[x][0]=0;    pushup(x);    pushup(rt);} void solve(int k){    int x=kth(rt,pos);    splay(x,rt);    cnt=0;    out(ch[rt][1],k);    puts("");}int main(){    n=read();pos=1;    build(rt,0,0,1," ");    while(n--)    {        scanf("%s",op+1);        if(op[1]=='P') pos--;        else if(op[1]=='N') pos++;        else if(op[1]=='M')        {            int x=read();            pos=x+1;        }        else if(op[1]=='I')        {            int x=read();            for(int i=0;i<x;i++)            {                s[i]=getchar();                if(s[i]=='\n') i--;            }            insert(s,x);        }        else if(op[1]=='D')        {            int x=read();            del(x);        }        else        {            int x=read();            solve(x);        }    }}
原创粉丝点击