LCA ST 模板

#include<bits/stdc++.h>
using namespace std;

const int N =1e5+5; /// 节点的个数
int rmq[N*2]; /// 就是欧拉序列对应的深度序列

struct ST
{
    int mm[N*2];
    int anc[2*N][20];
    void init(int n)
    {
        mm[0]=-1;
        for(int i=1;i<=n;i++){
            mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
            anc[i][0]=i;
        }
        for(int j=1;j<=mm[n];j++){
            for(int i=1;i+(1<<j)-1<=n;i++){
                anc[i][j]=rmq[anc[i][j-1]] < rmq[anc[i+(1<<(j-1))][j-1]]?anc[i][j-1]:anc[i+(1<<(j-1))][j-1];
            }
        }
    }

    int query(int a,int b)
    {
        if(a>b) swap(a,b);
        int k=mm[b-a+1];
        return rmq[anc[a][k]] <= rmq[anc[b-(1<<k)+1][k]]?anc[a][k]:anc[b-(1<<k)+1][k];
    }
};

struct node
{
    int v,next;
}edge[N*2];

int tot,head[N];
int dfns[N*2]; ///  欧拉序列,也就是dfs序,  长度为2*n-1, 下标从1 开始.
int pp[N];  /// pp[i] 表示在dfns 中第一次出现的位置
int L[N],R[N]; /// 表示当前节点dfs序中管辖的区间看情况使用
int cnt;
int clo; /// 时钟标记 用于L,R
ST st;

void init()
{
    tot=0;
    memset(head,-1,sizeof(head));
}

void add(int u,int v)
{
    edge[++tot].v=v; edge[tot].next=head[u]; head[u]=tot;
}

void dfs(int u,int fa,int deep)
{
    dfns[++cnt]=u; rmq[cnt]=deep; pp[u]=cnt;
    L[u]=++clo;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==fa) continue;
        dfs(v,u,deep+1);
        dfns[++cnt]=u;
        rmq[cnt]=deep;
    }
    R[u]=clo;
}

void LCA_init(int rt,int node_num)
{
    cnt=0;
    dfs(rt,rt,0);
    st.init(2*node_num-1);
}

int query_lca(int u,int v)
{
    return dfns[st.query(pp[u],pp[v])];
}

///  init 初始化边, LCA_init() 初始化lca

int main()
{
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yjt9299/article/details/81698406