RMQ求LCA模板:

//#pragma comment(linker,"/STACK:327680000,327680000")

#include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val)    memset(arr, val, sizeof(arr))



#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define ll __int64

#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("din.txt", "r", stdin)

#define Write() freopen("dout.txt", "w", stdout);





#define M 150

#define N 10007

using namespace std;





struct node

{

    int v,w;

    int next;

}g[N];

int head[N],ct;



int vNum[2*N],fNum[N],depth[2*N];

int cnt;

int dp[2*N][20];

int pow2[20],ind[N];

bool vt[N];

int n;



void init()

{

    cnt = 0;

    CL(head,-1);

    CL(ind,0);

    ct = 0;

}

void add(int u,int v)

{

    g[ct].v = v;

    g[ct].next = head[u];

    head[u] = ct++;

}

void dfs(int u,int dep)

{

    vt[u] = true;

    vNum[cnt] = u;//记录dfs的每个节点

    depth[cnt] = dep;//记录dfs每个节点的深度

    fNum[u] = cnt;//记录每节点第一次出现的编号

    cnt++;

    for (int i = head[u]; i != -1; i = g[i].next)

    {

        int v = g[i].v;

        if (!vt[v])

        {

            dfs(v,dep + 1);

            vNum[cnt] = u;

            depth[cnt] = dep;

            cnt++;

        }

    }

}

int imin(int i,int j)

{

    if (depth[i] < depth[j]) return i;

    else return j;

}

void init_rmq()

{

    int i,j;

    for (i = 0; i < cnt; ++i) dp[i][0] = i;

    for (j = 1; pow2[j] <= cnt; ++j)

    {

        for (i = 0; i + pow2[j] - 1 < cnt; ++i)

        {

            dp[i][j] = imin(dp[i][j - 1],dp[i + pow2[j - 1]][j - 1]);

        }

    }

}

int rmq(int l,int r)

{

    int k = (int)(log(1.0*(r - l + 1))/log(2.0));

    return imin(dp[l][k],dp[r - pow2[k] + 1][k]);

}

int main()

{

    int i,T;

    int x,y;

    for (i = 0; i <= 20; ++i) pow2[i] = 1<<i;

    scanf("%d",&T);

    while (T--)

    {

        scanf("%d",&n);

        init();

        for (i = 0; i < n - 1; ++i)//n-1条边

        {

            scanf("%d%d",&x,&y);

            ind[y]++;//统计每个节点入度找出根节点

            add(x,y);

        }

        //找根节点

        int root = 0;

        for (i = 1; i <= n; ++i)

        {

            if (ind[i] == 0)

            {

                root = i;

                break;

            }

        }

        //dfs给每一个节点编号,并且记录深度

        CL(vt,false);

        dfs(root,0);

        //rmq处理

        init_rmq();

        scanf("%d%d",&x,&y);

        if (fNum[x] <= fNum[y]) printf("%d\n",vNum[rmq(fNum[x],fNum[y])]);

        else printf("%d\n",vNum[rmq(fNum[y],fNum[x])]);

    }

    return 0;

}

  

 

你可能感兴趣的:(MQ)