LCA模板

离线trajan:

int find(int x)  
{  
    if(x==pre[x])return x;  
    return pre[x]=find(pre[x]);  
}  
  
void unite(int a,int b)  
{  
    int x=find(x),y=find(b);  
    pre[y]=x;  
}  
void LCA(int u)  
{  
    pre[u]=u;  
    ance[u]=u;  
    vis[u]=1;  
    int len=g[u].size();  
    for(int i=0;i<len;i++)  
    {  
        int v=g[u][i].first;  
        int w=g[u][i].second;  
        if(vis[v])continue;  
        dis[v]=dis[u]+w;  
        LCA(v);  
        unite(u,v);  
        ance[find(v)]=u;  
    }  
  
    len=q[u].size();  
    for(int i=0;i<len;i++)  
    {  
        int v=q[u][i].second;  
        int x=ance[find(v)];  
        if(vis[v])  
            ans[q[u][i].first]=dis[v]+dis[u]-2*dis[x];  
    }  
}  

在线RMQ:

void init()  
{  
    for(int i=0;i<=n;i++)g[i].clear();  
    num=0;  
    memset(pos,-1,sizeof(pos));  
    memset(vis,0,sizeof(vis));  
    memset(dis,0,sizeof(dis));  
}  
  
void dfs(int u,int depth)  
{  
    E[++num]=u,dep[num]=depth;  
    if(pos[u]==-1)pos[u]=num;  
    vis[u]=1;  
    int len=g[u].size();  
    for(int i=0;i<len;i++)  
    {  
        int v=g[u][i].first;  
        int w=g[u][i].second;  
        if(vis[v])continue;  
        dis[v]=dis[u]+w;  
        dfs(v,depth+1);  
        E[++num]=u;  
        dep[num]=depth;  
    }  
}  
  
void initRMQ(int len)  
{  
    for(int i=0;i<=len;i++)d[i][0]=i;  
    for(int j=1;(1<<j)<=len;j++)  
        for(int i=1;i+(1<<j)<=len;i++)  
        {  
            int x=d[i][j-1],y=d[i+(1<<(j-1))][j-1];  
            if(dep[x]<=dep[y])d[i][j]=x;  
            else d[i][j]=y;  
        }  
}  
  
int LCA(int x,int y)  
{  
    int a=pos[x],b=pos[y];  
    if(a>b)swap(a,b);  
    int k=0;  
    while((1<<(k+1))<=b-a+1)k++;  
    int l=d[a][k],r=d[b-(1<<k)+1][k];  
    if(dep[l]<dep[r])return E[l];  
    return E[r];  
}  

在线lrj版:

vector<int> edge[maxn];
int dep[maxn],fa[maxn],anc[maxn][30];
int num[maxn];
void dfs(int u,int f,int depth)
{
    dep[u]=depth;
    fa[u]=f;
    num[u]=1;
    int len=edge[u].size();
    for(int i=0;i<len;i++)
    {
        int v=edge[u][i];
        if(v==f)continue;
        dfs(v,u,depth+1);
        num[u]+=num[v];
        fa[v]=u;
    }
}
void preprocess()
{
    for(int i=1;i<=N;i++)
    {
        anc[i][0]=fa[i];
        for(int j=1;(1<<j)<=N;j++)anc[i][j]=-1;
    }
    for(int j=1;(1<<j)<=N;j++)
    {
        for(int i=1;i<=N;i++)
        {
            if(anc[i][j-1]==-1)continue;
            int a=anc[i][j-1];
            anc[i][j]=anc[a][j-1];
        }
    }
}
int LCA(int p,int q)
{
    if(dep[p]<dep[q])swap(p,q);
    int k=0;
    while((1<<(k+1))<=dep[p])k++;
    for(int i=k;i>=0;i--)
        if(dep[p]-(1<<i)>=dep[q])
        p=anc[p][i];
    if(p==q)return p;
    for(int i=k;i>=0;i--)
        if(anc[p][i]!=-1&&anc[p][i]!=anc[q][i])
            p=anc[p][i],q=anc[q][i];
    return fa[p];
}
//往上走dis步
int jump(int u,int dis)
{
    if(dis==0)return u;
    for(int i=19;i>=0;i--)
        if((1<<i)<=dis)
            u=anc[u][i],dis-=(1<<i);
    return u;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值