西安集训第六天-----一般的数据结构知识

艾教为了留出一天时间给claris讲课
把两天的内容压缩到了一天讲,结果讲得自己扛不住了。。。(滑稽

在学习这节课之前,其实应该有以下知识:

  1. 树链剖分: 学习资料http://blog.csdn.net/acdreamers/article/details/10591443
    顾名思义,这个算法本质即将一棵树划分成许多链然后进行void dfs2(int u,int tp)
    {
    top[u]=tp;
    tid[u]=++tim;
    rank[tid[u]]=u;
    if(son[u]==-1) return;
    dfs2(son[u],tp);
    for(int i=head[u];~i;i=next[i])
    {
    int v=to[i];
    if(v!=son[u]&&v!=fa[u])
    dfs2(v,v);
    }
    }
    void dfs2(int u,int tp)
    {
    top[u]=tp;
    tid[u]=++tim;
    rank[tid[u]]=u;
    if(son[u]==-1) return;
    dfs2(son[u],tp);
    for(int i=head[u];~i;i=next[i])
    {
    int v=to[i];
    if(v!=son[u]&&v!=fa[u])
    dfs2(v,v);
    }
    }
    处理。
    首先,我们可以划分成两种链:轻链和重链。我们定义size[i] 表示i的子树的节点数。 那么对于某个节点u,它的所有儿子中存在一个size 最大的节点v,可以形成重边(u,v),其余边为轻边。(如果存在多个儿子size相同,随意选一条即可,这个不关键) ,重边形成重链,轻边形成轻链。剖分完之后,整棵树=若干条重链+若干条轻链。
    性质1:对与轻边(u,v) 肯定存在 size[v] <=size[u]/2; 证明很简单,假设size[v]=x,使size[u]最小,那么存在一条重边( u, i )且其size[i]=x+1, 此时size[u]=x+x+1。
    性质2:因为存在性质1,所以我们可以推得从跟到某点的路径最多经过的重链和轻链都不会超过log个。
    所以重链—重链之间的跳跃也不会超过log次。
    过程:两次dfs,第一次找出所有重边,第二次连接所有重边:以根节点为起点,沿着重边向下拓展,拉成重链,不在当前重链上的节点,都以该节点为起点向下重新拉一条重链。

siz[]数组,用来保存以x为根的子树节点个数
son[]数组,用来保存重儿子
dep[]数组,用来保存当前节点的深度
fa[]数组,用来保存当前节点的父亲

void dfs1(int u,int father,int d)
{
    dep[u]=d;
    fa[u]=father;
    siz[u]=1;
    for(int i=head[u];~i;i=next[i])
    {
        int v=to[i];
        if(v!=father)
        {
            dfs1(v,u,d+1);
            siz[u]+=siz[v];
            if(son[u]==-1||siz[v]>siz[son[u]])
                son[u]=v;
        }
    }
}

top[]数组,用来保存当前节点的所在链的顶端节点
tid[]数组,用来保存树中每个节点剖分后的新编号
rank[]数组,用来保存当前节点在线段树中的位置
dfs2:
⒈对于u,当son[u]存在(即v不是叶子节点)时,显然有top[son[u]] = top[u]。线段树中,u的重边应当在u的父边的后面,即编号在tim后面,totw表示最后加入的一条边在线段树中的位置。此时,为了使一条重链各边在线段树中连续分布,应当进行dfs_2(son[v]);
⒉对于v的各个轻儿子u,显然有top[u] = u,并且fa[u] = totw+1,进行dfs_2过程。

void dfs2(int u,int tp)
{
    top[u]=tp;
    tid[u]=++tim;
    rank[tid[u]]=u;
    if(son[u]==-1) return;
    dfs2(son[u],tp);
    for(int i=head[u];~i;i=next[i])
    {
        int v=to[i];
        if(v!=son[u]&&v!=fa[u])
            dfs2(v,v);
    }
}

可以从网上找几个树链剖分的模板题做做:
SPOJ375——Query on a tree(树链剖分模板详解以及入门);
题解:http://blog.csdn.net/say_c_box/article/details/52126753

2.并查集
这个不用多讲,不过PPT上有很多大开眼界的例题呢。

3.LCA在讲课的时候我们只要知道模板即可。

这节课将会学会的内容: 可持久化思想,树链剖分,和简单的Splay

热身题:

猜你喜欢

转载自blog.csdn.net/qq_24664053/article/details/76854288