Least Common Ancestor

struct LeastCommonAncestor
{
    static const int __=10005;
    static const int logn=15;
    struct edge
    {
        int x,val;
        edge(int x,int y):
            x(x),val(y) {}
    };

    vectorG[__];
    int n,pre[__][logn],dis[__][logn],dep[__];

    void add_edge(int x,int y,int z)
    {
        G[x].pb(edge(y,z));
    }

    void dfs(int x,int fa,int dist)
    {
        pre[x][0]=fa,dis[x][0]=dist,dep[x]=dep[fa]+1;
        fup(i,0,sz(G[x])-1)
            if(G[x][i].x!=fa)
                dfs(G[x][i].x,x,G[x][i].val);
    }

    void init(int _n)
    {
        n=_n;
        dfs(1,0,0);
        fup(i,1,logn-1)
            fup(j,1,n)
            {
                pre[j][i]=pre[pre[j][i-1]][i-1];
                dis[j][i]=dis[j][i-1]+dis[pre[j][i-1]][i-1];
            }
    }

    int get_lca(int x,int y)
    {
        if(dep[x]=dep[y])
                x=pre[x][i];
        if(x==y)return x;
        fdn(i,logn-1,0)
            if(pre[x][i]!=pre[y][i])
                x=pre[x][i],y=pre[y][i];
        return pre[x][0];
    }

    int get_dis(int x,int y)
    {
        if(dep[x]=dep[y])
                sum+=dis[x][i],x=pre[x][i];
        if(x==y)return sum;
        fdn(i,logn-1,0)
            if(pre[x][i]!=pre[y][i])
                sum+=dis[x][i]+dis[y][i],x=pre[x][i],y=pre[y][i];
        sum+=dis[x][0]+dis[y][0];
        return sum;
    }

    int get_kth(int x,int y,int k)
    {
        int lca=get_lca(x,y);
        if(k==dep[x]-dep[lca]+1)return lca;
        if(k=(1<dep[x]-dep[lca]+1)
        {
            k=dep[x]+dep[y]-2*dep[lca]-k+1;
            fdn(i,logn-1,0)
                if(pre[y][i] && k>=(1<

题目链接:最近公共祖先

树链剖分:

struct bian
{
    int nex,nex_node;
    bian(int nex=0,int nex_node=0):
        nex(nex),nex_node(nex_node) {}
} edge[1000005];

int head[500005],edge_num=0;

void add_edge(int now,int nex)
{
    edge[edge_num]=bian(nex,head[now]);
    head[now]=edge_num++;
}

int pre[500005],dep[500005];
int top[500005],heavy[500005];

int dfs(int x,int fa,int depth)
{
    dep[x]=depth,pre[x]=fa;
    int res=1,maxx=0;
    for(int i=head[x]; ~i; i=edge[i].nex_node)
    {
        int nex=edge[i].nex;
        if(nex==fa)continue;
        int t=dfs(nex,x,depth+1);
        if(t>maxx)maxx=t,heavy[x]=nex;
        res+=t;
    }
    return res;
}

void slpf(int x,int fa,int tp)
{
    top[x]=tp;
    if(heavy[x])slpf(heavy[x],x,tp);
    for(int i=head[x]; ~i; i=edge[i].nex_node)
    {
        int nex=edge[i].nex;
        if(nex==fa)continue;
        if(nex!=heavy[x])slpf(nex,x,nex);
    }
}

int lca(int x,int y)
{
    while(top[x]!=top[y])
        if(dep[top[x]]>dep[top[y]])
            x=pre[top[x]];
        else y=pre[top[y]];
    if(dep[x]>dep[y])swap(x,y);
    return x;
}

int main()
{
    memset(head,-1,sizeof(head));
    int n,q,root,x,y;
    scanf("%d%d%d",&n,&q,&root);
    for(int i=1; i<=n-1; i++)
    {
        scanf("%d%d",&x,&y);
        add_edge(x,y);
        add_edge(y,x);
    }
    dfs(root,0,1);
    slpf(root,0,root);
    while(q--)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    }
    return 0;
}

Tarjan(离线)算法:

原创模板:
int n;
vectorG[10005];
int pre[10005];
int vis[10005];
int alr[10005];

void init(int x)
{
    for(int i=1; i<=x; i++)
        pre[i]=i;
}

int a,b;

int find(int x)
{
    if(pre[x]==x)return x;
    else return find(pre[x]);
}

int flag=0;

void dfs(int x,int fa)
{
    if(flag)return;
    int len=G[x].size();
    for(int i=0; i

RMQ-ST(在线)算法:

struct node
{
    int val,id;
};

vectorG[500005];
int vis[500005];
int first[500005];
node minn[500005][21];
int cont=1;

void dfs(int node,int depth)
{
    minn[cont][0].id=node;
    if(!first[node])first[node]=cont;
    minn[cont++][0].val=depth;
    int len=G[node].size();
    for(int i=0; ir)swap(l,r);
    while((1<<(k+1))<=r-l+1)k++;
    if(minn[l][k].val

题目链接:最近公共祖先

在线:
struct node
{
    int val,id;
};
mapmp1;
mapmp2;
vectorG[200005];
int deep[200005],order[200005],first[200005],pre[200005],cont;
bool vis[200005];
node minn[200005][20];
void dfs(int node,int depth)
{
    vis[node]=true;
    order[cont]=node;
    if(!first[node])first[node]=cont;
    deep[cont++]=depth;
    int len=G[node].size();
    for(int i=0; ir)swap(l,r);
    while((1<<(k+1))<=r-l+1)k++;
    if(minn[l][k].val

题目链接:最近公共祖先

离线:
struct node
{
    int nex,id;
} t;

int pre[100005];
int ans[100005];
bool vis[100005];
bool alr[100005];
char re[100005][50];
mapmp;
vectorG[100005];
vectorQue[100005];

int find(int x)
{
    if(pre[x]==x)return x;
    else 
    return pre[x]=find(pre[x]);
}

void dfs(int fa,int x)
{
    int len=G[x].size();
    for(int i=0; i

题目链接:最近公共祖先

LCT:

#define ls(x) tree[x].lson
#define rs(x) tree[x].rson
#define fa(x) tree[x].pre
#define grafa(x) tree[tree[x].pre].pre

struct bian
{
    int nex,nex_node;
    bian(int x=0,int y=0):
        nex(x),nex_node(y) {}
} edge[1000005];

int head[500005],edge_num=0;

void add_edge(int now,int nex)
{
    edge[edge_num]=bian(nex,head[now]);
    head[now]=edge_num++;
}

int path_pre[500005];

void dfs(int x,int fa)
{
    path_pre[x]=fa;
    for(int i=head[x]; ~i; i=edge[i].nex_node)
    {
        int nex=edge[i].nex;
        if(nex==fa)continue;
        dfs(nex,x);
    }
}

struct node
{
    int pre,lson,rson;
    int val,siz;
    node(int pre=-1,int lson=-1,int rson=-1,
         int val=0,int siz=0):
        pre(pre),lson(lson),rson(rson),
        val(val),siz(siz) {}
} tree[500005];


int root=-1;

void pushup(int x)
{
    tree[x].siz=1;
    if(~ls(x))
        tree[x].siz+=tree[ls(x)].siz;
    if(~rs(x))
        tree[x].siz+=tree[rs(x)].siz;
}

void zig(int x)
{
    int y=fa(x);
    if(~fa(y))
        if(ls(fa(y))==y)
            ls(fa(y))=x;
        else rs(fa(y))=x;
    fa(x)=fa(y),fa(y)=x;
    ls(y)=rs(x);
    if(~ls(y))fa(ls(y))=y;
    rs(x)=y;
    if(fa(x)==-1)root=x;
    pushup(y),pushup(x);
}

void zag(int x)
{
    int y=fa(x);
    if(~fa(y))
        if(ls(fa(y))==y)
            ls(fa(y))=x;
        else rs(fa(y))=x;
    fa(x)=fa(y),fa(y)=x;
    rs(y)=ls(x);
    if(~rs(y))fa(rs(y))=y;
    ls(x)=y;
    if(fa(x)==-1)root=x;
    pushup(y),pushup(x);
}

void splay(int x,int wz=-1)
{
    while(x!=wz && fa(x)!=wz)
        if(grafa(x)==wz)
            if(ls(fa(x))==x)zig(x);
            else zag(x);
        else if(ls(fa(x))==x && ls(grafa(x))==fa(x))
            zig(fa(x)),zig(x);
        else if(rs(fa(x))==x && rs(grafa(x))==fa(x))
            zag(fa(x)),zag(x);
        else if(ls(fa(x))==x && rs(grafa(x))==fa(x))
            zig(x),zag(x);
        else if(rs(fa(x))==x && ls(grafa(x))==fa(x))
            zag(x),zig(x);
}

int aux_root(int x)
{
    while(~ls(x))x=ls(x);
    return x;
}

int access(int x)
{
    int deper=-1;
    while(~x)
    {
        splay(x);
        fa(rs(x))=-1;
        rs(x)=deper;
        pushup(x);
        if(~deper)fa(deper)=x;
        deper=x;
        x=path_pre[aux_root(x)];
    }
    return deper;
}

int lca(int x,int y)
{
    access(x);
    return access(y);
}

void show(int n)
{
    for(int i=1;i<=n;i++)
        printf("%d: ls:%d rs:%d fa:%d\n",i,ls(i),rs(i),fa(i));
}

int main()
{
    memset(head,-1,sizeof(head));
    int n,q,root;
    scanf("%d%d%d",&n,&q,&root);
    for(int i=1; i

你可能感兴趣的:(Least Common Ancestor)