lca_mrq模板

 
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int N = 4e4 + 1;
int n,step;
int vs[2 * N], dp[2*N][20], id[N], depth[2 * N];

/*
1.除id以外,其他数组都是2*N;
2.若选择半闭半开 dp时这里分为 [i][j-1] [i+1<<(j-1)][j-1]
3.lca时把区间分为 [L][i-1] [R+1-1<<(i-1)][i-1]    这里是减号 上面是加号
4.lca返回vs[i];
5.初始化有两个;dfs和rmq_dp
*/

struct edge
{
    int to, dis;
    edge(int t, int d) :to(t), dis(d) {};
};
vector<edge>graph[N];

void dfs(int from, int to, int dep, int&step)
{
    id[to] = step;
    vs[step] = to;
    depth[step++] = dep;

    int size = graph[to].size();
    for (int i = 0; i < size; ++i)
        if (graph[to][i].to != from)
        {
            dfs(to, graph[to][i].to, dep + 1, step);

            vs[step] = to;
            depth[step++] = dep;
        }
}
  
void rmq_dp()
{
    for (int i = 0; i < step; ++i)
        dp[i][0] = i;
    for (int j = 1; 1 << j < step; ++j)
        for (int i = 0; (i + (1 << j)) < step; ++i)
        {
            int a = dp[i][j - 1];
            int b = dp[i + (1 << (j - 1))][j - 1];
            dp[i][j] = depth[a] < depth[b] ? a : b;
        }
}

int lca(int L, int R)
{
    L = id[L];
    R = id[R];
    if (L > R)
        swap(L, R);

    int i = 0;
    while (1 << i < R - L + 1)
        ++i;
    
    int a = dp[L][i - 1];
    int b = dp[R - (1 << (i - 1)) + 1][i - 1];
    return depth[a] < depth[b] ? vs[a] : vs[b];
}

int main()
{
    step = 0;
    dfs(0, 0, 0, step);
    rmq_dp();//然后就可以用了
}
    
 

猜你喜欢

转载自www.cnblogs.com/zqzqzqzqzq/p/9175420.html