zoukankan      html  css  js  c++  java
  • 洛谷 P3391 文艺平衡树

    题目描述

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

                    --by洛谷

    http://daniu.luogu.org/problem/show?pid=3391



    裸的平衡树反转;

    方法是按序列位置为关键字排序;

    反转(l,r):

    则将l-1置于根处,将r+1作为根的右儿子,这样,r+1的左子树就是需要反转的区间;

    然后对r+1的左儿子,反转其左右儿子,并打上线段树一样的lazy标记,待以后反转她的子树;

    一开始,企图把位置维护为关键字,然后排序;

    这样,

    若点A为父节点的左儿子,则key[A]=key[fa[A]]-size[rs[A]]-1;

    若点A为父节点的右儿子,则key[A]=key[fa[A]]+size[ls[A]]+1;

    然后查找直接按查询关键字的方法找,十分方便;

    然而关键字是时时变化的,不好维护,

    另一种方法是直接在初次建好树后就再也不考虑维护关键字的问题,

    直接按第K大的方法搜索,(从某种意义上讲她早已不是一般意义上的查找树了)

    怎么办,选哪种方法继续呢?

    一个很好的方法是把两个都写出来,

    反正差不多

    多好啊,还能对拍,是吧

    代码如下:

      1 #include<cstdio>
      2 using namespace std;
      3 int n,m;
      4 struct dt{
      5     int cnt,size,key,lz;
      6     int ch[2],fa;
      7 };
      8 struct Splay{
      9     int root,tot;
     10     dt data[100010];
     11     void in(){
     12         root=tot=0;
     13         data[0].fa=data[0].cnt=data[0].size=data[0].key=0;
     14     }
     15     void splay(int x,int end){
     16         int fa,fafa;
     17         for(fa=data[x].fa;(fa=data[x].fa)!=end;roll(x)){
     18             fafa=data[fa].fa;
     19             if(fafa!=end){
     20                 if((data[fafa].ch[1]==fa)^(data[fa].ch[1]==x))
     21                     roll(x);
     22                 else
     23                     roll(fa);
     24             }
     25         }
     26         if(!end)
     27             root=x;
     28     }
     29     void roll(int x){
     30         int fa=data[x].fa,fafa=data[fa].fa;
     31         int wh=data[fa].ch[1]==x;
     32         data[fa].ch[wh]=data[x].ch[wh^1];data[data[x].ch[wh^1]].fa=fa;
     33         data[x].ch[wh^1]=fa;data[fa].fa=x;
     34         if(fafa)
     35             data[fafa].ch[data[fafa].ch[1]==fa]=x;
     36         data[x].fa=fafa;
     37         up(fa);up(x);
     38     }
     39     void up(int x){
     40         data[x].size=data[data[x].ch[0]].size+data[data[x].ch[1]].size+1;
     41     }
     42     void buil_splay(int l,int r,int&nu,int fa){
     43         int mid=(l+r)>>1;
     44         nu=++tot;
     45         data[nu].key=mid;
     46         data[nu].fa=fa;
     47         data[nu].cnt=data[nu].size=1;
     48         if(l==r)return;
     49         if(l<mid)
     50             buil_splay(l,mid-1,data[nu].ch[0],nu);
     51         if(r>mid)
     52             buil_splay(mid+1,r,data[nu].ch[1],nu);
     53         data[nu].size=data[data[nu].ch[0]].size+data[data[nu].ch[1]].size+1;
     54     }
     55     int find(int x){
     56         int i=root;
     57         while(!(data[data[i].ch[0]].size<x&&x<=data[i].size-data[data[i].ch[1]].size)){
     58             if(data[i].lz){
     59                 change(data[i].ch[0]);
     60                 change(data[i].ch[1]);
     61                 data[i].lz=0;
     62             }
     63             if(x<=data[data[i].ch[0]].size)
     64                 i=data[i].ch[0];
     65             else{
     66                 x-=(data[i].size-data[data[i].ch[1]].size);
     67                 i=data[i].ch[1];
     68             }
     69         }
     70         if(data[i].lz){
     71             change(data[i].ch[0]);
     72             change(data[i].ch[1]);
     73             data[i].lz=0;
     74         }
     75         return i;
     76     }
     77     void change(int x){
     78         int fa=data[x].fa,i;
     79             i=data[x].ch[0];data[x].ch[0]=data[x].ch[1];data[x].ch[1]=i;
     80             data[x].lz^=1;
     81     }
     82     void print(int now){
     83         if(data[now].lz){
     84             change(data[now].ch[0]);
     85             change(data[now].ch[1]);
     86             data[now].lz=0;
     87         }
     88         if(data[now].ch[0])
     89             print(data[now].ch[0]);
     90         if(data[now].key!=0&&data[now].key!=n+1)
     91             printf("%d ",data[now].key);
     92         if(data[now].ch[1])
     93             print(data[now].ch[1]);
     94     }
     95 };
     96 Splay splay;
     97 int main()
     98 {
     99     int i,j,k,l;
    100     scanf("%d%d",&n,&m);
    101     splay.buil_splay(0,n+1,splay.root,0);
    102     for(i=1;i<=m;i++){
    103         scanf("%d%d",&j,&k);
    104         if(j==k)continue;
    105         l=splay.find(j);
    106         splay.splay(l,0);
    107         l=splay.find(k+2);
    108         splay.splay(l,splay.root);
    109         splay.change(splay.data[splay.data[splay.root].ch[1]].ch[0]);
    110     }
    111     splay.print(splay.root);
    112 }
    View Code

      

      1 #include<cstdio>
      2 using namespace std;
      3 int n,m;
      4 struct dt{
      5     int value,cnt,size,key,lz;
      6     int ch[2],fa;
      7 };
      8 struct Splay{
      9     int root,tot;
     10     dt data[100010];
     11     void in(){
     12         root=tot=0;
     13         data[0].fa=data[0].cnt=data[0].size=data[0].value=data[0].key=0;
     14     }
     15     void splay(int x,int end){
     16         int fa,fafa;
     17         for(fa=data[x].fa;(fa=data[x].fa)!=end;roll(x)){
     18             fafa=data[fa].fa;
     19             if(fafa!=end){
     20                 if((data[fafa].ch[1]==fa)^(data[fa].ch[1]==x))
     21                     roll(x);
     22                 else
     23                     roll(fa);
     24             }
     25         }
     26         if(!end)
     27             root=x;
     28     }
     29     void roll(int x){
     30         int fa=data[x].fa,fafa=data[fa].fa;
     31         int wh=data[fa].ch[1]==x;
     32         data[fa].ch[wh]=data[x].ch[wh^1];data[data[x].ch[wh^1]].fa=fa;
     33         data[x].ch[wh^1]=fa;data[fa].fa=x;
     34         if(fafa)
     35             data[fafa].ch[data[fafa].ch[1]==fa]=x;
     36         data[x].fa=fafa;
     37         up(fa);up(x);
     38     }
     39     void up(int x){
     40         data[x].size=data[data[x].ch[0]].size+data[data[x].ch[1]].size+1;
     41     }
     42     void buil_splay(int l,int r,int&nu,int fa){
     43         int mid=(l+r)>>1;
     44         nu=++tot;
     45         data[nu].value=data[nu].key=mid;
     46         data[nu].fa=fa;
     47         data[nu].cnt=data[nu].size=1;
     48         if(l==r)return;
     49         if(l<mid)
     50             buil_splay(l,mid-1,data[nu].ch[0],nu);
     51         if(r>mid)
     52             buil_splay(mid+1,r,data[nu].ch[1],nu);
     53         data[nu].size=data[data[nu].ch[0]].size+data[data[nu].ch[1]].size+1;
     54     }
     55     int find(int x){
     56         int i=root;
     57         while(1){
     58             change(data[i].ch[0]);
     59             change(data[i].ch[1]);
     60             data[i].lz=0;
     61             if(data[i].value==x)
     62                 break;
     63             i=data[i].ch[data[i].value<x];
     64         }
     65         return i;
     66     }
     67     void change(int x){
     68         int fa=data[x].fa,i;
     69         if(data[fa].lz){
     70                 i=data[x].ch[0];data[x].ch[0]=data[x].ch[1];data[x].ch[1]=i;
     71                 data[x].lz^=1;
     72             }
     73         if(data[fa].ch[0]==x)
     74             data[x].value=data[fa].value-data[data[x].ch[1]].size-1;
     75         else
     76             data[x].value=data[fa].value+data[data[x].ch[0]].size+1;
     77     }
     78     void print(int now){
     79         change(data[now].ch[0]);
     80         change(data[now].ch[1]);
     81         data[now].lz=0;
     82         if(data[now].ch[0])
     83             print(data[now].ch[0]);
     84         if(data[now].key!=0&&data[now].key!=n+1)
     85             printf("%d ",data[now].key);
     86         if(data[now].ch[1])
     87             print(data[now].ch[1]);
     88     }
     89 };
     90 Splay splay;
     91 int main()
     92 {
     93     int i,j,k,l;
     94     scanf("%d%d",&n,&m);
     95     splay.buil_splay(0,n+1,splay.root,0);
     96     for(i=1;i<=m;i++){
     97         scanf("%d%d",&j,&k);
     98         if(j==k)continue;
     99         l=splay.find(j-1);
    100         splay.splay(l,0);
    101         l=splay.find(k+1);
    102         splay.splay(l,splay.root);
    103         splay.data[splay.data[splay.root].ch[1]].lz=1;
    104         splay.change(splay.data[splay.data[splay.root].ch[1]].ch[0]);
    105         splay.data[splay.data[splay.root].ch[1]].lz=0;
    106     }
    107     splay.print(splay.root);
    108 }
    another_way

    祝AC

  • 相关阅读:
    使用virtualenvwrapper隔离python环境
    Ubuntu创建launcher
    Python单步调试
    Jupyter增加内核
    扩展User增加部门字段
    EasyUI ComboBox默认值
    C#调用dll时的类型转换
    更改VisualStudio默认创建类和接口不加public问题
    IL学习资料
    服务注册中心,Eureka比Zookeeper好在哪里?
  • 原文地址:https://www.cnblogs.com/nietzsche-oier/p/6670928.html
Copyright © 2011-2022 走看看