zoukankan      html  css  js  c++  java
  • 初识Splay树

    yyb大佬的入门讲解:http://www.cnblogs.com/cjyyb/p/7499020.html

    Orz

    我就补充一下Splay树怎么作为区间树使用:

    1、Splay树作为一种二叉排序树,对其中序dfs遍历后的结果便是按key值从小到大排序的数列,那么我们将编号作为key值即可。

    2、如果要获取到[l,r]区间的数列,则利用Splay操作将l-1作为根,r+1作为根的右节点,再对r+1的左子树中序遍历。

    3、上面似乎并没有体现区间树的效率优势。。

    4、模仿线段树的做法,每个节点除了维护自身的信息外,还需维护以自己为根的这棵树对应的区间的信息,维护的信息会在rotate操作时发生改变,则在rotate操作时更新节点的信息。

    5、lazy_tag,在节点信息变更或查询时,记得提前把lazy_tag下传。

    洛谷的区间翻转裸题:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<algorithm>
      7 #include<map>
      8 using namespace std;
      9 #define N 100005
     10 struct Node{
     11     int ch[2]; //左右儿子
     12     int val;
     13     int ff;
     14     int size;
     15     int tag; 
     16 }node[N];
     17 int tot=1,root=0;
     18 inline void push_up(int x)  //refresh
     19 {    int lson=node[x].ch[0];
     20     int rson=node[x].ch[1];
     21     node[x].size=node[lson].size+node[rson].size+1;
     22 }
     23 inline void push_down(int x) //down lazy_tag
     24 {    if(node[x].tag)
     25     {
     26     node[x].tag=0;
     27     int lson=node[x].ch[0];
     28     int rson=node[x].ch[1];
     29     node[lson].tag^=1;
     30     node[rson].tag^=1;
     31     swap(node[x].ch[0],node[x].ch[1]);
     32     }
     33 }
     34 inline void rotate1(int x)
     35 {
     36     int y=node[x].ff;
     37     int z=node[y].ff;
     38     int k=(node[y].ch[1]==x);
     39     node[z].ch[node[z].ch[1]==y]=x;
     40     node[x].ff=z;
     41     
     42     node[y].ch[k]=node[x].ch[k^1];
     43     node[node[x].ch[k^1]].ff=y;
     44     
     45     node[x].ch[k^1]=y;
     46     node[y].ff=x;
     47     push_up(y);
     48     push_up(x);
     49 }
     50 inline void splay(int x,int goal) //把x节点伸展到goal节点下 
     51 {
     52     while(node[x].ff!=goal)
     53     {
     54         int y=node[x].ff;
     55         int z=node[y].ff;
     56         if(z!=goal)
     57             (node[y].ch[0]==x)^(node[z].ch[0]==y)?rotate1(x):rotate1(y);
     58         rotate1(x);
     59     }
     60     if(goal==0)root=x;
     61 }
     62 inline void ins(int v)
     63 {
     64     int u=root,ff=0;
     65     while(u&&node[u].val!=v)
     66     {    ff=u;
     67         u=node[u].ch[v>node[u].val];
     68     }
     69     if(u) ;
     70     else
     71     {
     72         u=tot++;
     73         node[ff].ch[v>node[ff].val]=u;
     74         node[u].ff=ff;
     75         node[u].ch[0]=node[u].ch[1]=0;
     76         node[u].val=v;
     77         node[u].size=1;
     78     }
     79     splay(u,0);
     80 }
     81 inline int find_k(int k)
     82 {    int u=root;
     83     while(u)
     84     {    push_down(u);
     85         int lson=node[u].ch[0];
     86         if(node[lson].size==k-1) return u;
     87         if(node[lson].size<k-1)
     88         {
     89             u=node[u].ch[1];
     90             k-=node[lson].size+1;
     91         }
     92         else
     93         {
     94             u=node[u].ch[0];
     95         }
     96     }
     97     return -1;
     98 }
     99 int n,m,a[N],tt=0;
    100 void dfs_w(int x)
    101 {    if(!x) return;
    102     push_down(x);
    103     dfs_w(node[x].ch[0]);
    104     a[tt++]=node[x].val;
    105     dfs_w(node[x].ch[1]);    
    106 }
    107 int main()
    108 {
    109     
    110     cin>>n>>m;
    111     for(int i=1;i<=n+2;i++)  //增加头尾两个哨兵 
    112     {
    113         ins(i);
    114     }
    115     while(m--)
    116     {
    117         int l,r;
    118         scanf("%d%d",&l,&r);
    119         l=find_k(l);
    120         r=find_k(r+2);
    121         splay(l,0);
    122         splay(r,l);
    123         node[node[r].ch[0]].tag^=1;
    124     }
    125     dfs_w(root);
    126     for(int i=1;i<n;i++)
    127         printf("%d ",a[i]-1);
    128     printf("%d
    ",a[n]-1);
    129     
    130     return 0;
    131 }
  • 相关阅读:
    codeforces 1140D(区间dp/思维题)
    区间dp之四边形不等式优化详解及证明
    poj1947
    hdu4044
    poj1155
    poj3162(树形dp+优先队列)
    hdu4003详解(树形dp+多组背包)
    poj1947(树形背包)
    hdu1011(树形背包)(提供一个特殊样例)
    CopyOnWriteArrayList总结
  • 原文地址:https://www.cnblogs.com/lnu161403214/p/9304360.html
Copyright © 2011-2022 走看看