Least Common Ancestors

/* Least Common Ancestors
 * Au: Small_Ash
 */
#include <bits/stdc++.h>
using namespace std;

const int N = 500005, M = 1000005, MM = 20;

int n, m, s, d[N], l[N], f[M], fn; // d 是深度,l 是最左边对应位置,f 是 dfs 序
bool v[N]; // dfs 标记
int head[N], nex[M], to[M], en; // 邻接表
int r[M][MM]; // RMQ 用

inline void add(int x, int y) {
    nex[++en] = head[x], head[x] = en, to[en] = y;
}
inline void push(int x) {
    f[fn] = x; fn++;
}

void rmq() {
    for (int i = 0; i < fn; i++) r[i][0] = f[i];
    for (int j = 1; (1 << j) <= fn; j++)
        for (int i = 0; i + (1 << j) - 1 < fn; i++) {
            if (d[r[i][j - 1]] <= d[r[i + (1 << (j - 1))][j - 1]]) r[i][j] = r[i][j - 1];
            else r[i][j] = r[i + (1 << (j - 1))][j - 1];
        }
}

void dfs(int x, int t) {
    v[x] = true; d[x] = t;
    l[x] = fn, push(x);

    for (int k = head[x]; k; k = nex[k]) {
        if (v[to[k]]) continue;
        dfs(to[k], t + 1);
        push(x);
    }
}

int lca(int  x, int y) {
    int k = 0; if (x > y) swap(x, y);
    int temp = y - x + 1;
    while ((1 << (k + 1)) <= temp) k++;
    if (d[r[x][k]] <= d[r[y - (1 << k) + 1][k]]) return r[x][k];
    else return r[y - (1 << k) + 1][k];
}

int main() {
    scanf("%d%d%d", &n, &m, &s);
    for (int i = 1, a, b; i < n; i++) {
        scanf("%d%d", &a, &b);
        add(a, b), add(b, a);
    }

    fn = 0;
    dfs(s, 0);
    rmq();

    for (int i = 1, a, b; i <= m; i++) {
        scanf("%d%d", &a, &b);
        printf("%d\n", lca(l[a], l[b]));
    }

    return 0;
}
/**
 * Least Common Ancestors
 * std: [Luogu](https://www.luogu.org/problem/show?pid=3379)
 **/

#include <bits/stdc++.h>
using namespace std;

const int N = 1000003;

int n, rmq[N][23], t, x, y;

int query(int l, int r) {
	int k = int(log(r - l + 1) / log(2));
	return max(rmq[l][k], rmq[r + 1 - (1 << k)][k]);
}

void st() {
	for (int i = 1; i <= n; i++)
		scanf("%d", &rmq[i][0]);
	for (int j = 1; j <= int(log(n) / log(2)); j++)
		for (int i = 1; i + (1 << j) - 1 <= n; i++)
			rmq[i][j] = max(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
}

int main() {
	scanf("%d%d", &n, &t);

	st();

	for (int i = 1; i <= t; i++) {
		scanf("%d%d", &x, &y);
		printf("%d\n", query(x, y));
	}
	return 0;
}
posted @ 2017-10-18 21:00  greyqz  阅读(102)  评论(0编辑  收藏  举报