【[NOI2003]文本编辑器】

题目

发现这样一句话就会导致\(T\)

ch[m][0]=++m;

并不是很知道为什么,可能这是某种未定义行为在不同编译器下会有不同后果?

至于这道题就很简单了,几个有关光标位置的操作就用一个变量模拟就好了

插入的话把这个位置转出来构造一棵完美\(splay\)插入就好了

删除直接转出区间断开的父亲的链接

输出直接转出区间中序遍历

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 2100005
#define re register
char opt[15],S[maxn],val[maxn];
int n,root,pos,m,len;
int fa[maxn],ch[maxn][2],sz[maxn];
inline void update(int x) {sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;}
inline void rotate(int x) {
    int y=fa[x],z=fa[y],k=ch[y][1]==x,w=ch[x][k^1];
    ch[z][ch[z][1]==y]=x,ch[x][k^1]=y,ch[y][k]=w;
    update(y),update(x),fa[w]=y,fa[y]=x,fa[x]=z;
}
inline void splay(int x,int goal) {
    while(fa[x]!=goal) {
        int y=fa[x];
        if(fa[y]!=goal) rotate((ch[y][1]==x)^(ch[fa[y]][1]==y)?x:y);
        rotate(x);
    }
    if(!goal) root=x;
}
inline int kth(int x) {
    int u=root;
    while(1) {
        if(sz[ch[u][0]]>=x) u=ch[u][0];
            else if(x>sz[ch[u][0]]+1) x-=sz[ch[u][0]]+1,u=ch[u][1];
                else return u;
    }
}
void dfs(int x) {
    if(ch[x][0]) dfs(ch[x][0]);
    putchar(val[x]);
    if(ch[x][1]) dfs(ch[x][1]);
}
int build(int x,int y,int f) {
    if(x>y) return 0;
    if(x==y) {
        val[++m]=S[x];sz[m]=1;fa[m]=f;
        return m;
    }
    int mid=x+y>>1,rt=++m;
    val[rt]=S[mid];fa[rt]=f;
    ch[rt][0]=build(x,mid-1,rt),ch[rt][1]=build(mid+1,y,rt);update(rt);
    return rt;
}
int main()
{
    scanf("%d",&n);
    pos=1;
    root=++m;sz[m]=2;ch[1][0]=++m;
    sz[m]=1;fa[m]=1;
    while(n--) {
        scanf("%s",opt);
        if(opt[0]=='M') scanf("%d",&pos),pos++;
        if(opt[0]=='P') pos--;
        if(opt[0]=='N') pos++;
        if(opt[0]=='I') {
            scanf("%d",&len);S[0]=' ';
            for(re int i=1;i<=len;i++) {
                S[i]=getchar();
                if(S[i]=='\n'||S[i]=='\r') --i;
            }
            int aa=kth(pos),bb=kth(pos+1);
            splay(aa,0),splay(bb,aa);
            int t=ch[root][1],rt=build(1,len,t);
            ch[t][0]=rt,update(t),splay(t,0);
        }
        if(opt[0]=='D') {
            scanf("%d",&len);
            int aa=kth(pos),bb=kth(pos+len+1);
            splay(aa,0),splay(bb,aa);
            ch[ch[root][1]][0]=0;update(ch[root][1]);splay(ch[root][1],0);
        }
        if(opt[0]=='G') {
            scanf("%d",&len);
            int aa=kth(pos),bb=kth(pos+len+1);
            splay(aa,0),splay(bb,aa);
            dfs(ch[ch[root][1]][0]);putchar(10);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/asuldb/p/10364636.html