在线LCA

const int MAXN = 10010;  /*******************Online & SegmentTree********************************/
const int MAXM = 10010;  
  
struct N  
{  
    int v,w,next;  
}edge[MAXM*2];  
int Top;  
int head[MAXN];  
int MAXSIZE;  
int dep[MAXN];  
int seq[MAXN*2];  
int R[MAXN];  
  
struct ST  
{  
    int dep,point;  
    bool operator < (const ST &A) const  
    {  
        return dep < A.dep;  
    }  
}st[MAXN*8];  
  //若为无向图则w = 1。
void Link(int u,int v,int w)  
{  
    edge[Top].v = v;  
    edge[Top].w = w;  
    edge[Top].next = head[u];  
    head[u] = Top++;  
}  
  
void Init()  
{  
    memset(head,-1,sizeof(head));  
    Top = 0;  
    MAXSIZE = 0;  
}  
  
void InitDep(int s,int pre = -1,int d = 0)  
{  
    R[s] = ++MAXSIZE;  
    seq[MAXSIZE] = s;  
    dep[s] = d;  
  
    for(int p =  head[s]; p != -1; p = edge[p].next)  
    {  
        if(edge[p].v != pre)  
        {  
            InitDep(edge[p].v,s,d+edge[p].w);  
            seq[++MAXSIZE] = s;  
        }  
    }  
}  
  
void InitST(int site,int l,int r)  
{  
    if(l == r)  
    {  
        st[site].dep = dep[seq[l]];  
        st[site].point = seq[l];  
        return ;  
    }  
  
    int mid = (l+r)>>1;  
  
    InitST(site<<1,l,mid);  
    InitST(site<<1|1,mid+1,r);  
  
    st[site] = st[site<<1].dep < st[site<<1|1].dep ? st[site<<1] : st[site<<1|1];  
}  
  
ST QueryLCA(int site,int L,int R,int l,int r)  
{  
    if(L == l && R == r)  
        return st[site];  
  
    int mid = (L+R)>>1;  
  
    if(r <= mid)  
        return QueryLCA(site<<1,L,mid,l,r);  
    else if(mid < l)  
        return QueryLCA(site<<1|1,mid+1,R,l,r);  
  
    return min(QueryLCA(site<<1,L,mid,l,mid),QueryLCA(site<<1|1,mid+1,R,mid+1,r));  
  
} 


/*********************Online & multiply**********************************/
int pa[MAXN][MAXM];
int dep[MAXN];

void InitFaDep(int s,int pre = -1,int d = 0)
{
    pa[s][0] = pre;
    dep[s]  = d;
    for(int p = head[s];p != -1; p = edge[p].next)
    {
        if(edge[p].v != pre)
            InitFaDep(edge[p].v,s,d+1);
    }
}

void InitPa(int n)
{
    int i,j,t;

    for(j = 1,t = 2;j < MAXM;t <<= 1,++j)
    {
        for(i = 1;i <= n ; ++i)
        {
            if(pa[i][j-1] != -1)
                pa[i][j] = pa[pa[i][j-1]][j-1];
            else
                pa[i][j] = -1;
        }
    }
}

int QueryLCA(int u,int v)
{
    if(dep[u] < dep[v])
        swap(u,v);

    for(int j = MAXM-1;j >= 0; --j)
    {
        if(pa[u][j] != -1 && dep[u]-(1<<j) >= dep[v])
                u = pa[u][j];
    }

    if(u == v) return u;

    for(int j = MAXM-1;j >= 0; --j)
    {
        if(pa[u][j] != -1 && pa[u][j] != pa[v][j])
            u = pa[u][j],v = pa[v][j];
    }

    return pa[u][0];
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值