zoukankan      html  css  js  c++  java
  • ST表求LCA

    复习一下

    几个地方需要注意,lg2 数组要预处理,s数组是遍历顺序(不要手残打成DFS序)

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 2000005;
    vector <int> g[N];
    int n,m,rt,st[N][20],dep[N],dis[N],vis[N],ind,lg2[N],s[N],bg[N],ed[N];
    
    void dfs(int p) {
        vis[p]=1;
        s[++ind]=p;
        bg[p]=ind;
        for(int q:g[p]) {
            if(vis[q]==0) {
                dep[q]=dep[p]+1;
                dfs(q);
                s[++ind]=p;
            }
        }
        ed[p]=ind;
    }
    
    int lca(int p,int q) {
        p=bg[p]; q=bg[q];
        if(p>q) swap(p,q);
        int l=lg2[q-p+1];
        int x=st[p][l];
        int y=st[q-(1<<l)+1][l];
        return dis[x]<dis[y]?x:y;
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        scanf("%d%d%d",&n,&m,&rt);
        for(int i=0;i<=20;i++) for(int j=1<<i;j<1<<(i+1);j++) lg2[j]=i;
        for(int i=1;i<n;i++) {
            int t1,t2;
            scanf("%d%d",&t1,&t2);
            g[t1].push_back(t2);
            g[t2].push_back(t1);
        }
        dfs(rt);
        for(int i=1;i<=ind;i++) dis[i]=dep[s[i]];
        for(int i=1;i<=ind;i++) st[i][0]=i;
        for(int i=1;i<=19;i++) {
            for(int j=1;j<=ind;j++) {
                st[j][i]=dis[st[j][i-1]]<dis[st[j+(1<<(i-1))][i-1]]?
                        st[j][i-1]:st[j+(1<<(i-1))][i-1];
            }
        }
        for(int i=1;i<=m;i++) {
            int t1,t2;
            scanf("%d%d",&t1,&t2);
            printf("%d
    ",s[lca(t1,t2)]);
        }
    }
    
  • 相关阅读:
    表格维护:弹出
    表格联动
    表单查询
    浅谈分治 —— 洛谷P1228 地毯填补问题 题解
    The Captain 题解
    网课集训记
    2020-1-20寒假集训记
    博客使用声明
    JZOJ P5829 string 线段树
    线段树--CF438D The Child and Sequence
  • 原文地址:https://www.cnblogs.com/mollnn/p/12441246.html
Copyright © 2011-2022 走看看