2016.5.1

http://www.cnblogs.com/huangxincheng/archive/2012/07/22/2603956.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去找—-二分
查询时按照斜率去找—-二分

使用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方的算法!!!
–先把点从小到大排序,然后合并
–http://www.cnblogs.com/wuminyan/p/5205018.html题解
附题:
http://poj.org/problem?id=3580

你可能感兴趣的:(2016.5.1)