[bzoj1269][AHOI2006]文本编辑器editort

这道题跟noi2005的维护序列类似,而且要比它简单一点,故用splay的话,只要仔细认真即可,不是很难。

值得注意一点是在找前驱,后继等点时,不需要单独写一个过程,只要找出它们的位置(即它们是序列中第几个字符)即可。

const
	MAXN=2097152;
type
	date=record
		ch:array[0..1]of longint;
		f,sz,rev:longint;c:char;
	end;
var
	n,i,top,root,tst,p:longint;s:ansistring;
	st:array[0..MAXN+10]of longint;
	t:array[0..MAXN+10]of date;
procedure pushdown(k:longint);
var x:longint;
begin
	if(k=0)then exit;
	if(t[k].rev=1)then
	begin
		if(t[k].ch[0]<>0)then t[t[k].ch[0]].rev:=t[t[k].ch[0]].rev xor 1;
		if(t[k].ch[1]<>0)then t[t[k].ch[1]].rev:=t[t[k].ch[1]].rev xor 1;
		x:=t[k].ch[0];t[k].ch[0]:=t[k].ch[1];t[k].ch[1]:=x;
		t[k].rev:=0;
	end;
end;
procedure pushup(k:longint);
begin
	if(k=0)then exit;
	pushdown(k);pushdown(t[k].ch[0]);pushdown(t[k].ch[1]);
	t[k].sz:=t[t[k].ch[0]].sz+t[t[k].ch[1]].sz+1;
end;
function cmp(x,k:longint):longint;
begin
	if(t[x].ch[0]=k)then exit(0) else exit(1);
end;
procedure rotate(k,c:longint);
var i:longint;
begin
	i:=t[k].f;
	pushdown(i);pushdown(k);
	t[i].ch[c xor 1]:=t[k].ch[c];t[t[k].ch[c]].f:=i;t[k].ch[c]:=i;
	t[k].f:=t[i].f;
	if(t[i].f<>0)then t[t[i].f].ch[cmp(t[i].f,i)]:=k;
	t[i].f:=k;
	pushup(i);
end;
procedure splay(k,goal:longint);
var x,y,f1,f2:longint;
begin
	while(t[k].f<>goal)do
	begin
		x:=t[k].f;y:=t[x].f;
		if(y=goal)then rotate(k,cmp(x,k)xor 1)
		else begin
			f1:=cmp(y,x);f2:=cmp(x,k);
			if(f1<>f2)then begin rotate(x,f1 xor 1);rotate(k,f1 xor 1) end
			else begin rotate(k,f2 xor 1);rotate(k,f1 xor 1) end;
		end;
	end;
	pushup(k);
	if(goal=0)then root:=k;
end;
procedure rotateto(k,goal:longint);
var i:longint;
begin
	i:=root;
	pushdown(i);
	while(t[t[i].ch[0]].sz<>k)do
	begin
		if(k<t[t[i].ch[0]].sz)then i:=t[i].ch[0]
		else begin
			k:=k-t[t[i].ch[0]].sz-1;i:=t[i].ch[1];
		end;
		pushdown(i);
	end;
	splay(i,goal);
end;
procedure newnode(var x:longint;f:longint;c:char);
begin
	if(tst<>0)then begin x:=st[tst];dec(tst) end
	else begin inc(top);x:=top end;
	t[x].ch[0]:=0;t[x].ch[1]:=0;t[x].f:=f;t[x].c:=c;t[x].rev:=0;t[x].sz:=1;
end;
procedure maketree(var x:longint;l,r,f:longint);
var mid:longint;
begin
	if(l>r)then exit;
	mid:=(l+r)>>1;
	newnode(x,f,s[mid]);
	maketree(t[x].ch[0],l,mid-1,x);
	maketree(t[x].ch[1],mid+1,r,x);
	pushup(x);
end;
procedure init;
begin
	newnode(root,0,' ');
	newnode(t[root].ch[1],root,' ');
	pushup(root);
end;
procedure del(k:longint);
begin
	if(k=0)then exit;
	inc(tst);st[tst]:=k;
	del(t[k].ch[0]);del(t[k].ch[1]);
end;
procedure getchar;
var c:char;
begin
	s:='';
	read(c);
	while(not eoln)and(c<>' ')do
	begin
		s:=s+c;read(c);
	end;
	if(c<>' ')then s:=s+c;
end;
begin
	readln(n);
	init;
	for i:=1 to n do
	begin
		getchar;
		if(s='Move')then begin readln(p);rotateto(p,0) end;
		if(s='Insert')then
		begin
			readln(p);readln(s);
			rotateto(t[t[root].ch[0]].sz+1,root);
			maketree(t[t[root].ch[1]].ch[0],1,p,t[root].ch[1]);
		end;
		if(s='Delete')then
		begin
			readln(p);rotateto(t[t[root].ch[0]].sz+p+1,root);
			del(t[t[root].ch[1]].ch[0]);t[t[root].ch[1]].ch[0]:=0;
		end;
		if(s='Rotate')then
		begin
			readln(p);
			rotateto(t[t[root].ch[0]].sz+p+1,root);
			t[t[t[root].ch[1]].ch[0]].rev:=t[t[t[root].ch[1]].ch[0]].rev xor 1;
		end;
		if(s='Get')then
			begin
				readln;
				rotateto(t[t[root].ch[0]].sz+2,root);
				writeln(t[t[t[root].ch[1]].ch[0]].c)
			end;
		if(s='Prev')then begin readln;rotateto(t[t[root].ch[0]].sz-1,0);end;
		if(s='Next')then begin readln;rotateto(t[t[root].ch[0]].sz+1,0);end;
		pushup(t[root].ch[1]);pushup(root);
	end;
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值