• bzoj3223


    很久没写splay了,这是用splay解决动态区间问题
    平常splay树的建立都是以键值建立的
    而这里是以位置序号为优先级建立的
    不难发现,tree上的点代表的位置就是它的名次
    splay的区间操作最重要的一点就是提取区间
    设提取区间[a,b],则我们只要代表位置a-1的点伸展到根,再把代表位置b+1的点伸展到根的子树(显然在右子树)
    然后显然,b+1的左子树就表示区间[a,b]
    为了方便提取,我们常常会加入额外位置点0,n+1
    这道题比较简单,只有翻转操作
    显然这个是可以打标记的,每个点节点打上当前以这个点为根的子树是否要翻转
    我们先提取区间,然后在根节点节点打上标记,显然这就表示这个区间要翻转
    然后在之后的splay操作中维护这个标记即可

      1 var son:array[-1..100010,1..2] of longint;
      2     count,fa,a,b:array[-1..100010] of longint;
      3     v:array[-1..100010] of boolean;
      4     i,n,m,t,root,x,y:longint;
      5 
      6 procedure swap(var a,b:longint);
      7   var c:longint;
      8   begin
      9     c:=a;
     10     a:=b;
     11     b:=c;
     12   end;
     13 
     14 procedure change(x:longint);
     15   begin
     16     if x=-1 then exit;
     17     swap(son[x,1],son[x,2]);
     18     v[x]:=not v[x];
     19   end;
     20 
     21 procedure push(x:longint);
     22   begin
     23     if v[x] then
     24     begin
     25       change(son[x,1]);
     26       change(son[x,2]);
     27       v[x]:=false;
     28     end;
     29   end;
     30 
     31 procedure update(x:longint);
     32   begin
     33     count[x]:=count[son[x,1]]+count[son[x,2]]+1;
     34   end;
     35 
     36 procedure rotate(x,w:longint);
     37   var y:longint;
     38   begin
     39     push(x);
     40     y:=fa[x];
     41     if fa[y]<>-1 then
     42     begin
     43       if son[fa[y],1]=y then son[fa[y],1]:=x
     44       else son[fa[y],2]:=x;
     45     end;
     46     fa[x]:=fa[y];
     47     son[y,3-w]:=son[x,w];
     48     if son[x,w]<>-1 then fa[son[x,w]]:=y;
     49     son[x,w]:=y;
     50     fa[y]:=x;
     51     update(y);
     52     update(x);
     53   end;
     54 
     55 procedure splay(x,f:longint);
     56   var y:longint;
     57   begin
     58     while fa[x]<>f do
     59     begin
     60       y:=fa[x];
     61       if fa[y]=f then
     62       begin
     63         if son[y,1]=x then rotate(x,2)
     64         else rotate(x,1);
     65       end
     66       else begin
     67         if son[fa[y],1]=y then
     68         begin
     69           if son[y,1]=x then rotate(y,2) else rotate(x,1);
     70           rotate(x,2);
     71         end
     72         else begin
     73           if son[y,1]=x then rotate(x,2) else rotate(y,1);
     74           rotate(x,1);
     75         end;
     76       end;
     77     end;
     78     if f=-1 then root:=x;
     79   end;
     80 
     81 function build(l,r:longint):longint;
     82   var m:longint;
     83   begin
     84     m:=(l+r) shr 1;
     85     build:=m;
     86     if l<=m-1 then
     87     begin
     88       son[m,1]:=build(l,m-1);
     89       fa[son[m,1]]:=m;
     90     end;
     91     if m+1<=r then
     92     begin
     93       son[m,2]:=build(m+1,r);
     94       fa[son[m,2]]:=m;
     95     end;
     96     update(m);
     97   end;
     98 
     99 function find(k:longint):longint;
    100   var p:longint;
    101   begin
    102     p:=root;
    103     while true do
    104     begin
    105       push(p);
    106       if count[son[p,1]]+1=k then exit(p)
    107       else if count[son[p,1]]+1>k then p:=son[p,1]
    108       else begin
    109         k:=k-count[son[p,1]]-1;
    110         p:=son[p,2];
    111       end;
    112     end;
    113   end;
    114 
    115 procedure work(x,y:longint);
    116   begin
    117     x:=find(x);
    118     y:=find(y+2);
    119     splay(x,-1);
    120     splay(y,x);
    121     change(son[y,1]);
    122   end;
    123 
    124 procedure mid(x:longint);
    125   begin
    126     push(x);
    127     if son[x,1]<>-1 then mid(son[x,1]);
    128     inc(t);
    129     b[t]:=a[x];
    130     if son[x,2]<>-1 then mid(son[x,2]);
    131   end;
    132 
    133 begin
    134   fillchar(son,sizeof(son),255);
    135   fillchar(fa,sizeof(fa),255);
    136   readln(n,m);
    137   for i:=0 to n+1 do
    138     a[i]:=i;
    139   root:=build(0,n+1);  //先直接建立一棵平衡的BST
    140   for i:=1 to m do
    141   begin
    142     readln(x,y);
    143     work(x,y);
    144   end;
    145   t:=-1;
    146   mid(root);
    147   for i:=1 to t-1 do
    148     write(b[i],' ');
    149 end.
    View Code
  • 相关阅读:
    委托与事件的关系
    分布式存储ceph——(1)部署ceph
    neutron二
    openstack第五章:cinder
    openstack第六章:dashboard
    openstack第一章:keystone
    openstack第二章:glance
    openstack第三章:nova
    openstack第四章:neutron— 网络服务
    openstack安装
  • 原文地址:https://www.cnblogs.com/phile/p/4473040.html
Copyright © 2020-2023  润新知