2016.5.1
2016-05-01 15:39
155 查看
/article/4582416.html
splay–伸展树
三个操作 插入 查询 删除
**插入 O(2*lgn)
while(x不是根)
root(x)
rotation
可以root(x)–单旋
也可以root(father[x])再root(x)–双旋
treap=tree+heap树加堆
按照value保存一棵二叉搜索树的性质
按照weight保存堆的性质
value左中右递增
weight根节点最小
如果value和weight都不同那么这棵二叉搜索树是唯一确定的
期望高度为O(lgn)
**插入:
通过旋转操作来维护堆性质
o<在插入的路径中向上旋转,不会影响其他子树
插入一个点:每一次O(lgn)—-树的高度lgn
**删除:
把需要删除的点按到最下面—如何实现呢
把weight设为无穷大
然后就有了两种旋转方式
1—把右儿子拽上来
2—把左儿子拽上来
如何选择呢
那个儿子小就把哪个拽上来
**>o<
函数treap可以不依赖旋转
用空间换时间
线段树需要离散化—基于二进制
红黑树—基于大小比较
线段树必须有固定的len,而二叉树不需要,是动态的
凸包—好名字>o< T_T
先找到最左边的节点和最右边的节点
**如果左边有多个,那么取最上和最下的两个
然后分别找到上凸壳和下凸壳
如何找呢
维护一个栈
使得每条线的斜率都是单调递降的—这样就使得每两条相邻的线的凸包内的夹角都小于180°
每个点的x都是单调递增的—这是显然的>o<
**因为有单调性 >o< 所以有以下方法:
加点时按照x去找—-二分
查询时按照斜率去找—-二分
并查集
1.union x,y 把xy连在一起
2.same x,y 询问xy是否在一起
same操作可以转换为当前集合代表元是否相同
代表元将每一个连通块存储为树的形式
那么代表元就可以选为这棵有根树的根节点
如果有当前命令union(x,y)
那么找到x的代表元和y的代表元,也就是father(x)和father(y)
然后将x所在的树和y所在的树合并,于是并查集只需要保存每个节点的father
如果这棵树是一条链,那么每个节点找代表元最差为O(n)
怎么解决呢?
**>o<
1.按秩合并
每次合并都把深度较小的集合合并在深度较大的集合下面
秩–树的高度
如果size[x]>size[y]那么把y合并到x上—-O(lgn)
可以让代表元保存整棵树的size其他点可以不保存
**>o<
2.路径压缩
均摊分析
每一个点的father都直接设为代表元
简单应用:
1.连接:找连通块
2.某一连通块中的点的个数:按秩合并size
3.最小生成树:直接找代表元
4.缩点
5.合并相邻点—扫描线,eg.合并i和i+1 f[i]=i+1; 最大->右边 O(lgn)**每一个相邻的点都可以合并为一个,于是每一个合并的点都只被访问一次
复杂应用:
1.在边上保存信息
eg.x1……..xn非0即1
–给出一些语句
–问是否有矛盾语句
–有两种语句xi=xj,xi!=xj
–在边上维护,每个点是否与父亲相同
–如果相等
–合并,并且设为与父亲相同
–不相等
–合并,与父亲不同
–路径压缩
2.区间最值
eg.给一个序列,给出一些区间(li,ri)询问严格第二小的数(如果有多个第二小的数,选择最右边的数),可以离线
–有m个询问,最差mlgn,期望mαn的算法
–并查集啊( ⊙ o ⊙ )!典型例题呀!T_T >o<
–每一个向右边连边,每条边上维护从这个点到他的father的最小值,这样就可以保存区间(x,fx)的最小值
–如何路径压缩呢 若mx=(x,fx)最小值,那么ffx=min(mx,mfx)
–对于ri排序,如果要把ri向右移一位,那么就把当前点的father设为右边的点,然后路径压缩
–然而它可以被线段树替代呀
3.保存整个连通块上的信息
eg.平面上n个点,分成k块,要求满足一块内最远的距离小于不同块的最近距离。问对于n个点,哪些k可行**只有5000个点
**【BZOJ 1821】 [JSOI2010]Group 部落划分 Group >o<为什么是权限题!!!!!!!!
–还要严格n方的算法!!!
–先把点从小到大排序,然后合并
–/article/6462190.html题解
附题:
http://poj.org/problem?id=3580
splay–伸展树
三个操作 插入 查询 删除
**插入 O(2*lgn)
while(x不是根)
root(x)
rotation
可以root(x)–单旋
也可以root(father[x])再root(x)–双旋
treap=tree+heap树加堆
按照value保存一棵二叉搜索树的性质
按照weight保存堆的性质
value左中右递增
weight根节点最小
如果value和weight都不同那么这棵二叉搜索树是唯一确定的
期望高度为O(lgn)
**插入:
通过旋转操作来维护堆性质
o<在插入的路径中向上旋转,不会影响其他子树
插入一个点:每一次O(lgn)—-树的高度lgn
**删除:
把需要删除的点按到最下面—如何实现呢
把weight设为无穷大
然后就有了两种旋转方式
1—把右儿子拽上来
2—把左儿子拽上来
如何选择呢
那个儿子小就把哪个拽上来
**>o<
函数treap可以不依赖旋转
用空间换时间
线段树需要离散化—基于二进制
红黑树—基于大小比较
线段树必须有固定的len,而二叉树不需要,是动态的
凸包—好名字>o< T_T
先找到最左边的节点和最右边的节点
**如果左边有多个,那么取最上和最下的两个
然后分别找到上凸壳和下凸壳
如何找呢
维护一个栈
使得每条线的斜率都是单调递降的—这样就使得每两条相邻的线的凸包内的夹角都小于180°
每个点的x都是单调递增的—这是显然的>o<
**因为有单调性 >o< 所以有以下方法:
加点时按照x去找—-二分
查询时按照斜率去找—-二分
使用set query:flag=true; insert: flag=false; if(flag==true) return a.x < b.x; else return a.k < b.k;
并查集
1.union x,y 把xy连在一起
2.same x,y 询问xy是否在一起
same操作可以转换为当前集合代表元是否相同
代表元将每一个连通块存储为树的形式
那么代表元就可以选为这棵有根树的根节点
如果有当前命令union(x,y)
那么找到x的代表元和y的代表元,也就是father(x)和father(y)
然后将x所在的树和y所在的树合并,于是并查集只需要保存每个节点的father
int find(int x){ if(f[x]==x) return x; else return find(f[x]); } void union(x,y){ fx=find(x); fy=find(y); f[fy]=fx;//代表元相同 } void same(x,y){ return find(x)==find(y); }
如果这棵树是一条链,那么每个节点找代表元最差为O(n)
怎么解决呢?
**>o<
1.按秩合并
每次合并都把深度较小的集合合并在深度较大的集合下面
秩–树的高度
如果size[x]>size[y]那么把y合并到x上—-O(lgn)
可以让代表元保存整棵树的size其他点可以不保存
**>o<
2.路径压缩
均摊分析
int find(int x){ if(f[x]==x) return x; else return f[x]=find(f[x]); }
每一个点的father都直接设为代表元
简单应用:
1.连接:找连通块
2.某一连通块中的点的个数:按秩合并size
3.最小生成树:直接找代表元
4.缩点
5.合并相邻点—扫描线,eg.合并i和i+1 f[i]=i+1; 最大->右边 O(lgn)**每一个相邻的点都可以合并为一个,于是每一个合并的点都只被访问一次
复杂应用:
1.在边上保存信息
eg.x1……..xn非0即1
–给出一些语句
–问是否有矛盾语句
–有两种语句xi=xj,xi!=xj
–在边上维护,每个点是否与父亲相同
–如果相等
–合并,并且设为与父亲相同
–不相等
–合并,与父亲不同
–路径压缩
2.区间最值
eg.给一个序列,给出一些区间(li,ri)询问严格第二小的数(如果有多个第二小的数,选择最右边的数),可以离线
–有m个询问,最差mlgn,期望mαn的算法
–并查集啊( ⊙ o ⊙ )!典型例题呀!T_T >o<
–每一个向右边连边,每条边上维护从这个点到他的father的最小值,这样就可以保存区间(x,fx)的最小值
–如何路径压缩呢 若mx=(x,fx)最小值,那么ffx=min(mx,mfx)
–对于ri排序,如果要把ri向右移一位,那么就把当前点的father设为右边的点,然后路径压缩
–然而它可以被线段树替代呀
3.保存整个连通块上的信息
eg.平面上n个点,分成k块,要求满足一块内最远的距离小于不同块的最近距离。问对于n个点,哪些k可行**只有5000个点
**【BZOJ 1821】 [JSOI2010]Group 部落划分 Group >o<为什么是权限题!!!!!!!!
–还要严格n方的算法!!!
–先把点从小到大排序,然后合并
–/article/6462190.html题解
附题:
http://poj.org/problem?id=3580
相关文章推荐
- LeetCode 4. Median of Two Sorted Arrays(两个有序数组的中位数)
- 第 29 章 CSS3 弹性伸缩布局[上]
- 我的大学规划
- 读《Spring-技术内幕》-第二章:IoC容器的实现-1
- C语言编程程序的内存如何布局
- Genymotion 从注册到安装到运行到调试
- C++随笔
- PAT 1006. 换个格式输出整数 (15)
- 20145327 《Java程序设计》第九周学习总结
- day56-Spark SQL和DataFrame的本质
- 欢迎使用CSDN-markdown编辑器
- C 的布尔值
- PAT(Basic Level) 完美数列(25)
- apache+tomcat负载均衡
- 设置手机iphone5s邮件
- eclipse build workspace太慢或者 js出错问题解决
- Linux内核学习总结
- HTML学习小结
- make a list of your fans
- 第九周进度条