码迷,mamicode.com
首页 > 其他好文 > 详细

splay模板

时间:2014-06-19 00:38:25      阅读:1154      评论:0      收藏:0      [点我收藏+]

标签:style   class   blog   code   http   tar   

先贴一份不怎么完善的模板,等刷一些题目熟悉之后再来完善。代码参考自kuangbin及cxlove两位大神。

splay的基本功能

题目:维护一个数列,支持以下几种操作:

1. 插入:在当前数列第posi 个数字后面插入tot 个数字;若在数列首位插入,则posi 为0。

2. 删除:从当前数列第posi 个数字开始连续删除tot 个数字。

3. 修改:从当前数列第posi 个数字开始连续tot 个数字统一修改为c 。

4. 翻转:取出从当前数列第posi 个数字开始的tot 个数字,翻转后放入原来的位置。

5. 求和:计算从当前数列第posi 个数字开始连续tot 个数字的和并输出。

6. 求和最大子序列:求出当前数列中和最大的一段子序列,并输出最大和。

 

bubuko.com,布布扣
  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 200010
 12 #define LL __int64
 13 #define INF 0xfffffff
 14 #define key_value ch[ch[root][1]][0]
 15 const double eps = 1e-8;
 16 const double pi = acos(-1.0);
 17 const double inf = ~0u>>2;
 18 int pre[N],s[N],size[N];
 19 int ch[N][2],a[N],val[N],key[N];
 20 int root,n,tot;
 21 void dfs(int x)
 22 {
 23     if(x)
 24     {
 25         dfs(ch[x][0]);
 26         printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d add=%2d sum=%I64d\n",
 27                x,ch[x][0],ch[x][1],pre[x],size[x],key[x],add[x],s[x]);
 28         dfs(ch[x][1]);
 29     }
 30 }
 31 void debug()
 32 {
 33     printf("root:%d\n",root);
 34     dfs(root);
 35 }
 36 //以上用于debug
 37 void newnode(int &x,int k,int fa)//新建一结点
 38 {
 39     x = ++tot;
 40     ch[x][0]=ch[x][1] = 0;
 41     pre[x] = fa;
 42     size[x] = 1;
 43     s[x] = k;
 44     val[x] = k;
 45 }
 46 void pushup(int w)//由儿子更新其父亲
 47 {
 48     size[w] = size[ch[w][0]]+size[ch[w][1]]+1;
 49     s[w] = max(max(s[ch[w][0]],s[ch[w][1]]),val[w]);
 50 }
 51 void rotate(int r,int kind)//旋转操作,根据kind进行左旋和右旋
 52 {
 53     int y = pre[r];
 54     ch[y][!kind] = ch[r][kind];
 55     pre[ch[r][kind]] = y;
 56     if(pre[y])
 57     {
 58         ch[pre[y]][ch[pre[y]][1]==y] = r;
 59     }
 60     pre[r] = pre[y];
 61     ch[r][kind] = y;
 62     pre[y] = r;
 63     pushup(y);
 64 }
 65 void splay(int r,int goal)//将r结点旋至goal下
 66 {
 67     while(pre[r]!=goal)
 68     {
 69        if(pre[pre[r]]==goal)
 70         {
 71              rotate(r,ch[pre[r]][0]==r);
 72         }
 73         else
 74         {
 75             int y = pre[r];
 76             int kind = (ch[pre[y]][0]==y);
 77             if(ch[y][kind]==r)
 78             {
 79                 rotate(r,!kind);
 80                 rotate(r,kind);
 81             }
 82             else
 83             {
 84                 rotate(y,kind);
 85                 rotate(r,kind);
 86             }
 87         }
 88     }
 89     pushup(r);
 90     if(goal==0) root = r;
 91 }
 92 int get_k(int k)//得到第k个的结点
 93 {
 94     int r = root;
 95     while(size[ch[r][0]]!=k)
 96     {
 97         if(size[ch[r][0]]>k)
 98         r = ch[r][0];
 99         else
100         {
101             k-=(size[ch[r][0]]+1);//根据左右结点的数量来确定第k个节点在哪里
102             r = ch[r][1];
103         }
104     }
105     return r;
106 }
107 int query(int l,int r)//询问l,r区间,将第l-1个结点旋自根,第r+1个结点旋自根的有儿子,
108 {                       //则l-r就变成了根的右儿子的左儿子
109     splay(get_k(l-1),0);
110     splay(get_k(r+1),root);
111     return s[key_value];
112 }
113 void update(int l,int r,int k)//区间更新,类似于询问
114 {
115     splay(get_k(l-1),0);
116     splay(get_k(r+1),root);
117     val[key_value] = k;
118     s[key_value] = k;
119     pushup(ch[root][1]);
120     pushup(root);
121 }
122 void update(int l,int r,int k)//单点更新,将所求点旋至根
123 {
124     int kk = get_k(l);
125     val[kk] = k;
126     splay(kk,0);
127 }
128 void build(int &w,int l,int r,int fa)//递归建树
129 {
130     if(l>r) return ;
131     int m = (l+r)>>1;
132     newnode(w,a[m],fa);
133     build(ch[w][0],l,m-1,w);
134     build(ch[w][1],m+1,r,w);
135     pushup(w);
136 }
137 void init()//初始化操作,增加一个最小和最大值结点,防止越界
138 {
139     int i;
140     for(i = 0 ;i < n ;i++)
141     scanf("%d",&a[i]);
142     ch[0][0] = ch[0][1] = pre[0] = size[0] = s[0] = 0;
143     root = tot =0;
144     newnode(root,-1,0);
145     newnode(ch[root][1],-1,root);
146     size[root] = 2;
147     build(key_value,0,n-1,ch[root][1]);
148     pushup(ch[root][1]);
149     pushup(root);
150 }
View Code

 

 

splay模板,布布扣,bubuko.com

splay模板

标签:style   class   blog   code   http   tar   

原文地址:http://www.cnblogs.com/shangyu/p/3789609.html

(2)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!