【[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]=='
'||S[i]=='
') --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;
}
原文地址:https://www.cnblogs.com/asuldb/p/10364636.html