[SPLAY维护区间][BZOJ 3223][TYVJ 1729]文艺平衡树

来源:互联网 发布:mysql启动错误1067 编辑:程序博客网 时间:2024/05/16 14:57

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.


原创粉丝点击