Description
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
Analysis
那时TYVJ还没倒闭的时候,我平衡树学的是SBT...虽然常数完爆splay,但是maintain太难记了囧(现在已经全忘了我会说么)。
那时看到这道题没思路,之后noip后tyvj就倒闭了,也就没有接着做这题了。
然后某天晚上无聊切了[NOI2005]维修数列(其实还有一个下午),发现splay还能干这种事,而且好记又好写,卡常数这种丧心病狂的事又不是很可能遇到,就果断放弃SBT了...
题目相对于维修数列算是极水的,对于维护区间问题不会的,可以去翻JZP的论文和代码(C++和PASCAL都有)
上渣码:
type rec=record fa,l,r,val,siz:longint; rev:boolean; end;
var
n,m,i,x,y,root,tmp_root,total:longint;
t:array[-1..100010] of rec;
function new(x:longint):longint;
begin
inc(total);
new:=total;
with t[new] do begin
fa:=-1; l:=-1; r:=-1; val:=x; rev:=false; siz:=1;
end;
end;
procedure reverse(x:longint);
var
tt:longint;
begin
if x=-1 then exit;
tt:=t[x].l; t[x].l:=t[x].r; t[x].r:=tt;
t[x].rev:=not t[x].rev;
end;
procedure updata(x:longint);
begin
if x=-1 then exit;
t[x].siz:=t[t[x].l].siz+t[t[x].r].siz+1;
end;
procedure push_down(x:longint);
begin
if x=-1 then exit;
if t[x].rev then begin
reverse(t[x].l);
reverse(t[x].r);
t[x].rev:=false;
end;
end;
procedure zig(x:longint);
var
y,tmp:longint;
begin
y:=t[x].fa; tmp:=t[x].r;
push_down(y);
push_down(x);
if t[t[y].fa].l=y then t[t[y].fa].l:=x else t[t[y].fa].r:=x;
t[x].fa:=t[y].fa; t[x].r:=y;
t[y].l:=tmp; t[y].fa:=x; t[tmp].fa:=y;
updata(y);
end;
procedure zag(x:longint);
var
y,tmp:longint;
begin
y:=t[x].fa; tmp:=t[x].l;
push_down(y);
push_down(x);
if t[t[y].fa].l=y then t[t[y].fa].l:=x else t[t[y].fa].r:=x;
t[x].fa:=t[y].fa; t[x].l:=y;
t[y].r:=tmp; t[y].fa:=x; t[tmp].fa:=y;
updata(y);
end;
procedure splay(x,aim:longint);
var
y,tmp:longint;
begin
if x=-1 then exit;
push_down(x);
tmp:=t[aim].fa;
while t[x].fa<>tmp do begin
y:=t[x].fa;
if t[y].fa=tmp then if t[y].l=x then zig(x) else zag(x)
else begin
if t[t[y].fa].l=y then begin if t[y].l=x then zig(y) else zag(x); zig(x); end
else begin if t[y].r=x then zag(y) else zig(x); zag(x); end;
end;
end;
updata(x);
if tmp=-1 then root:=x;
end;
procedure select(k,aim:longint);
var
tt:longint;
begin
tt:=root;
while t[t[tt].l].siz+1<>k do begin
push_down(tt);
if t[t[tt].l].siz>=k then tt:=t[tt].l
else begin k:=k-t[t[tt].l].siz-1; tt:=t[tt].r; end;
end;
splay(tt,aim);
end;
function make_tree(l,r:longint):longint;
var
m,x:longint;
begin
if l>r then exit(-1);
m:=(l+r) shr 1;
x:=new(m);
t[x].l:=make_tree(l,m-1);
t[x].r:=make_tree(m+1,r);
if t[x].l<>-1 then t[t[x].l].fa:=x;
if t[x].r<>-1 then t[t[x].r].fa:=x;
updata(x);
exit(x);
end;
begin
root:=new(0);
t[root].r:=new(0);
t[t[root].r].fa:=root;
updata(root);
readln(n,m);
tmp_root:=make_tree(1,n);
t[t[root].r].l:=tmp_root;
t[tmp_root].fa:=t[root].r;
splay(t[root].r,root);
for i:=1 to m do begin
readln(x,y);
select(x,root);
select(y+2,t[root].r);
reverse(t[t[root].r].l);
end;
for i:=1 to n do begin
select(i+1,root);
write(t[root].val,' ');
end;
end.