普通版本:

 struct SplayTree
{ const static int maxn = 1e5 + ; int tot,root,ch[maxn][], key[maxn], val[maxn], sz[maxn], lz[maxn], fa[maxn]; void init( int x, int ky, int v = , int par = )
{
ch[x][]=ch[x][]=, fa[x]= par, key[x] = ky, val[x] = v, sz[x] = ;
} void init()
{
init( , , );
sz[] = ;
tot = root = ;
} inline void push_up(int x)
{
sz[x] = sz[ch[x][]] + sz[ch[x][]] + ;
} inline void push_down(int x)
{ } void rotate( int x, int d )
{
int y = fa[x];
ch[y][d ^ ] = ch[x][d];
if ( ch[x][d]) fa[ch[x][d]] = y;
fa[x] = fa[y];
if (fa[y])
{
if (y == ch[fa[y]][d]) ch[fa[y]][d] = x;
else ch[fa[y]][d ^ ] = x;
}
ch[x][d] = y, fa[y] = x;
push_up( y ), push_up( x );
} // Splay x to target's son
void Splay( int x, int target )
{
while( fa[x] != target )
{
int y = fa[x];
if( x == ch[y][] )
{
if( fa[y] != target && y == ch[fa[y]][])
rotate( y, );
rotate( x, );
}
else
{
if( fa[y] != target && y == ch[fa[y]][])
rotate( y, );
rotate( x, );
}
}
if( !target ) root = x;
} void Insert( int & t, int ky, int v, int par = )
{
if( t == )
{
t = ++ tot;
init( t, ky, v, par );
Splay( tot, );
}
else
{
int cur = t;
if( v < key[t] ) Insert( ch[t][], ky, v, cur );
else Insert( ch[t][], ky, v, cur );
push_up( cur );
}
} // Return point
int find( int t, int v )
{
if( t == ) return ;
else if( key[t] == v )
{
Splay( t, );
return t;
}
else if( v < key[t] ) return find( ch[t][], v );
return find( ch[t][], v );
} // Delete Root
void Delete()
{
if( !ch[root][] )
{
fa[ ch[root][] ] = ;
root = ch[root][];
}
else
{
int cur = ch[root][];
while( ch[cur][] ) cur = ch[cur][];
Splay( cur, root );
ch[cur][] = ch[root][];
root = cur, fa[cur] = , fa[ch[root][]] = root;
push_up( root );
}
} int size()
{
return sz[root];
}
// 查第 k 小 , 必须保证合法
int kth( int x, int k )
{
if( k == sz[ch[x][]] + )
{
Splay( x, );
return key[x];
}
else if( k <= sz[ch[x][]] ) return kth( ch[x][], k );
else return kth( ch[x][], k - sz[ch[x][]] - );
} //找前驱
int pred( int t, int v )
{
if( t == ) return v;
else
{
if( v <= key[t] ) return pred( ch[t][], v );
else
{
int ans = pred( ch[t][], v );
if( ans == v )
{
ans = key[t];
Splay( t, );
}
return ans;
}
}
} /*int less( int t , int v ){
if( t == 0 ) return 0;
int rs = 0;
if( v <= key[t] ) rs = less( ch[t][0] , v );
else rs = sz[ch[t][0]] + 1 + less( ch[t][1] , v );
if( Tl ){
Splay( t , 0 );
Tl = 0;
}
return rs;
}*/ //找后继
int succ( int t, int v )
{
if( t == ) return v;
else
{
if( v >= key[t] ) return succ( ch[t][], v );
else
{
int ans = succ( ch[t][], v );
if( ans == v )
{
ans = key[t];
Splay( t, );
}
return ans;
}
}
} void Preorder( int t )
{
if( !t ) return;
Preorder( ch[t][] );
printf("%d ", key[t] );
Preorder( ch[t][] );
} } sp;

区间更新版本-

 #include <bits/stdc++.h>

 using namespace std;

 #define lc ch[x][0]
#define rc ch[x][1]
#define pr fa[x] struct SplayTree
{ const static int maxn = 1e5 + ; int tot,root,ch[maxn][], key[maxn], val[maxn], sz[maxn], rev[maxn], fa[maxn]; inline int wh(int x){ return ch[pr][] == x;} inline void init( int x, int ky, int v = , int par = )
{
lc=rc=, fa[x]= par, key[x] = ky, val[x] = v, sz[x] = , rev[x] = ;
} inline void init()
{
init( , , );
sz[] = ;
tot = root = ;
} inline void push_up(int x)
{
sz[x] = sz[lc] + sz[rc] + ;
} inline void reverse(int x)
{
rev[x] ^= , swap( lc, rc);
} inline void push_down(int x)
{
if(rev[x])
{
if(lc) reverse(lc);
if(rc) reverse(rc);
rev[x] = ;
}
} void rotate( int x)
{
int f = fa[x], gf = fa[f], t1 = wh(x);
if( gf ) ch[gf][wh(f)] = x;
fa[x] = gf, ch[f][t1] = ch[x][^t1], fa[ch[f][t1]] = f;
ch[x][t1^] = f, fa[f] = x;
push_up( f ), push_up( x );
} void splay( int x, int tar )
{
for(; pr != tar; rotate(x))
if(fa[pr] != tar)
rotate( wh(x) == wh(pr) ? pr: x);
if( !tar ) root = x;
} void insert( int ky, int v)
{
int x = root, ls = root;
while(x)
{
push_down(x);
sz[x] ++, ls = x;
x = ch[x][ky > key[x]];
}
init( ++tot, ky, v, ls);
ch[ls][ky > key[ls]] = tot;
splay( tot, );
} int find( int ky)
{
int x = root;
while(x)
{
push_down(x);
if(key[x] == ky) break;
x = ch[x][ky > key[x]];
}
if(x) splay(x,);
else x = -;
return x;
} // Delete Root
void Delete()
{
if( !ch[root][] )
{
fa[ ch[root][] ] = ;
root = ch[root][];
}
else
{
int cur = ch[root][];
while( ch[cur][] ) cur = ch[cur][];
splay( cur, root );
ch[cur][] = ch[root][];
root = cur, fa[cur] = , fa[ch[root][]] = root;
push_up( root );
}
} int kth( int k)
{
int x = root;
if(sz[x] < k) return -;
while(x)
{
push_down(x);
if(k == sz[lc] + ) break;
if(k > sz[lc])
k -= sz[lc] + , x = rc;
else
x = lc;
}
if(x) splay(x,);
else x = -;
return x;
} int pred( void)
{
int x = root;
if(!x || !lc) return -;
x = lc;
while(rc) push_down(x), x = rc;
splay( x, );
return x;
} int succ( void)
{
int x = root;
if(!x || !rc) return -;
x = rc;
while(lc) push_down(x), x = lc;
splay( x, );
return x;
} void debug( int x )
{
if( !x ) return;
if(lc) debug( lc );
printf("%d ", key[x] );
if(rc) debug( rc );
} } sp; int main(void)
{
sp.init();
for(int i=,x;i<=;i++)
scanf("%d",&x),sp.insert(x,);
sp.debug(sp.root);
return ;
}

启发式合并:

 /**************************************************************
Problem: 2733
User: weeping
Language: C++
Result: Accepted
Time:4908 ms
Memory:4436 kb
****************************************************************/ #include <bits/stdc++.h> using namespace std; #define lc ch[x][0]
#define rc ch[x][1] int n,m,q,f[]; int fd(int x)
{
return f[x]==x?x:f[x]=fd(f[x]);
} struct SplayTree
{ const static int maxn = 1e5 + ; int tot,root,ch[maxn][], key[maxn], val[maxn], sz[maxn], rev[maxn], fa[maxn]; inline void init( int x, int ky, int v = , int par = )
{
lc=rc=, fa[x]= par, key[x] = ky, val[x] = v, sz[x] = , rev[x] = ;
} inline void init()
{
init( , , );
sz[] = ;
tot = root = ;
} inline void push_up(int x)
{
sz[x] = sz[lc] + sz[rc] + ;
} inline void reverse(int x)
{
rev[x] ^= , swap( lc, rc);
} inline void push_down(int x)
{
if(rev[x])
{
if(lc) reverse(lc);
if(rc) reverse(rc);
rev[x] = ;
}
} void rotate( int x)
{
int f = fa[x], gf = fa[f];
int t1 = (ch[f][] == x), t2 = (ch[gf][] == f);
if( gf ) ch[gf][t2] = x;
fa[x] = gf, ch[f][t1] = ch[x][^t1], fa[ch[f][t1]] = f;
ch[x][t1^] = f, fa[f] = x;
push_up( f ), push_up( x );
} void splay( int x, int tar )
{
for(int f = fa[x], gf = fa[f]; f != tar; rotate(x), f = fa[x], gf = fa[f])
if(gf != tar)
rotate( ((ch[f][] == x) == (ch[gf][] == f) )? f: x);
if( !tar ) root = x;
} void insert( int ky, int v)
{
int x = root, ls = root;
while(x)
{
push_down(x);
sz[x] ++, ls = x;
x = ch[x][ky > key[x]];
}
init( ++tot, ky, v, ls);
ch[ls][ky > key[ls]] = tot;
splay( tot, );
} int find( int ky)
{
int x = root;
while(x)
{
push_down(x);
if(key[x] == ky) break;
x = ch[x][ky > key[x]];
}
if(x) splay(x,);
else x = -;
return x;
} // Delete Root
void Delete()
{
if( !ch[root][] )
{
fa[ ch[root][] ] = ;
root = ch[root][];
}
else
{
int cur = ch[root][];
while( ch[cur][] ) cur = ch[cur][];
splay( cur, root );
ch[cur][] = ch[root][];
root = cur, fa[cur] = , fa[ch[root][]] = root;
push_up( root );
}
} int kth( int k)
{
int x = root;
if(sz[x] < k) return -;
while(x)
{
push_down(x);
if(k == sz[lc] + ) break;
if(k > sz[lc])
k -= sz[lc] + , x = rc;
else
x = lc;
}
if(x) splay(x,);
else x = -;
return x;
} int pred( void)
{
int x = root;
if(!x || !lc) return -;
x = lc;
while(rc) push_down(x), x = rc;
splay( x, );
return x;
} int succ( void)
{
int x = root;
if(!x || !rc) return -;
x = rc;
while(lc) push_down(x), x = lc;
splay( x, );
return x;
} void debug( int x )
{
if( !x ) return;
if(lc) debug( lc );
printf("%d ", key[x] );
if(rc) debug( rc );
} void qinsert(int y)
{
int x = root, ls = root, ky = key[y];
while(x)
ls = x, x = ch[x][ky > key[x]];
x = ls;
ch[x][ky > key[x]] = y,fa[y] = x, sz[y] = ;
splay(y, );
} void qmerge(int x)
{
if(!x) return;
int tl = lc, tr = rc;
lc = rc = ;
qmerge(tl);
qinsert(x);
qmerge(tr);
}
void merge(int u,int v)
{
if(u == v) return ;
if(sz[u]>sz[v]) swap(u,v);
f[u] = v, splay( v, );
qmerge(u);
}
} sp; int main(void)
{
scanf("%d%d",&n,&m);
for(int i=,x;i<=n;i++)
scanf("%d",&x),f[i]=i,sp.key[i]=x,sp.sz[i]=;
for(int i=,u,v;i<=m;i++)
scanf("%d%d",&u,&v),sp.merge(fd(u),fd(v));
scanf("%d",&q);
char op[];
for(int i=,x,y;i<=q;i++)
{
scanf("%s%d%d",op,&x,&y);
if(op[]=='B')
sp.merge(fd(x),fd(y));
else
sp.splay(x,),printf("%d\n",sp.kth(y));
}
return ;
}

splay伸展树模板的更多相关文章

  1. 【学时总结】◆学时·VI◆ SPLAY伸展树

    ◆学时·VI◆ SPLAY伸展树 平衡树之多,学之不尽也…… ◇算法概述 二叉排序树的一种,自动平衡,由 Tarjan 提出并实现.得名于特有的 Splay 操作. Splay操作:将节点u通过单旋. ...

  2. Splay伸展树学习笔记

    Splay伸展树 有篇Splay入门必看文章 —— CSDN链接 经典引文 空间效率:O(n) 时间效率:O(log n)插入.查找.删除 创造者:Daniel Sleator 和 Robert Ta ...

  3. Splay伸展树入门(单点操作,区间维护)附例题模板

    Pps:终于学会了伸展树的区间操作,做一个完整的总结,总结一下自己的伸展树的单点操作和区间维护,顺便给未来的自己总结复习用. splay是一种平衡树,[平均]操作复杂度O(nlogn).首先平衡树先是 ...

  4. Splay 伸展树

    废话不说,有篇论文可供参考:杨思雨:<伸展树的基本操作与应用> Splay的好处可以快速分裂和合并. ===============================14.07.26更新== ...

  5. [Splay伸展树]splay树入门级教程

    首先声明,本教程的对象是完全没有接触过splay的OIer,大牛请右上角.. 首先引入一下splay的概念,他的中文名是伸展树,意思差不多就是可以随意翻转的二叉树 PS:百度百科中伸展树读作:BoGa ...

  6. Codeforces 675D Tree Construction Splay伸展树

    链接:https://codeforces.com/problemset/problem/675/D 题意: 给一个二叉搜索树,一开始为空,不断插入数字,每次插入之后,询问他的父亲节点的权值 题解: ...

  7. HYSBZ 1500 维修数列(伸展树模板)

    题意: 题解:典型伸展树的题,比较全面. 我理解的伸展树: 1 伸展操作:就是旋转,因为我们只需保证二叉树中序遍历的结果不变,所以我们可以旋转来保持树的平衡,且旋转有左旋与右旋.通过这种方式保证不会让 ...

  8. UVA 11922 Permutation Transformer —— splay伸展树

    题意:根据m条指令改变排列1 2 3 4 … n ,每条指令(a, b)表示取出第a~b个元素,反转后添加到排列尾部 分析:用一个可分裂合并的序列来表示整个序列,截取一段可以用两次分裂一次合并实现,粘 ...

  9. [算法] 数据结构 splay(伸展树)解析

    前言 splay学了已经很久了,只不过一直没有总结,鸽了好久来写一篇总结. 先介绍 splay:亦称伸展树,为二叉搜索树的一种,部分操作能在 \(O( \log n)\) 内完成,如插入.查找.删除. ...

随机推荐

  1. CSS伪类选择器 - nth-child(an+b):

    CSS伪类选择器 - nth-child(an+b): 第一种:简单数字序号写法:nth-child(number)直接匹配第number个元素.参数number必须为大于0的整数.li:nth-ch ...

  2. Loadrunner如何遍历一个页面中的url并进行访问?

    最近在网上到一个关于loadrunner遍历一个页面中的url并进行访问的脚本,就把它用我们自己的项目实践了一下,发现有一点不完善. 原始版本: Action(){char temp[64];int ...

  3. STM32 PWM的输出与Keil软件仿真

    导读:PWM(Pulse Width Modulation)控制——脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形(含形状和幅值). PWM控制技术在逆变电路中应用最广,应用 ...

  4. IOS开发经验总结(二)

    本文转载至 http://dreamahui.iteye.com/blog/1878922 IOS开发总结 by mhmwadm (感谢mhmwadm) 2013/4/10 1 XCode快捷键 4  ...

  5. oracle修改用户密码

    1.使用oracle用户登录,连接数据库 [oracle@wuzj ~]$ sqlplus /nolog SQL*Plus: Release 10.2.0.1.0 - Production on Th ...

  6. IOS模拟器

    IOS模拟器 目录 概述 实用操作 概述 实用操作 快速删除大量程序的方式 菜单栏 -> Reset Contain And Settings 或者:直接删除模拟器应用里面的想要去除的应用程序的 ...

  7. [Domino]从嵌入另一个数据库嵌入的Embedded View无法正常显示,提示unable to lauch

    发现问题 1. 项目中需要在一个数据库中插入另一个数据库的Embedded View,使用起来十分费劲,在选择数据库的下拉菜单中经常会找不到目标数据库: 2. 在做日文版的时候,从workbench导 ...

  8. document.selection window.getSelection()

    IE9以下支持:document.selection  IE9.Firefox.Safari.Chrome和Opera支持:window.getSelection() 屏幕取词 function ge ...

  9. CentOS添加PHP至环境变量

    一,修改/etc/profile文件在尾部添加 PATH=$PATH:/usr/local/php/bin export PATH PATH后面跟着是的php的执行文档路径,可以追加多个以冒号分割 e ...

  10. Go语言 map的实现

    Go中的map在底层是用哈希表实现的,你可以在 $GOROOT/src/pkg/runtime/hashmap.goc 找到它的实现. 数据结构 哈希表的数据结构中一些关键的域如下所示: struct ...