【PAT1151】LCA in a Binary Tree(还原二叉树+LCA)

板题,明明物质能够解决的问题为什么要脑子解决呢QAQ

AC代码

#include <bits/stdc++.h>

typedef long long ll;
#define llinf 0x3f3f3f3f3f3f3f3f
#define inf 0x3f3f3f3f
#define SZ(x) (int)x.size()
#define mp make_pair
#define pii pair<int, int>
#define vi vector<int>
#define pb push_back

using namespace std;

unordered_map<int, int> um1, um2;

const int MAXN = 10005;


int a[MAXN], b[MAXN], na[MAXN], nb[MAXN];


int ch[MAXN][2], pos[MAXN]; // sons

namespace LCA {
    const int MAXLOG = 22;

    int dep[MAXN], fa[MAXN][MAXLOG], lg[MAXN];

    void init(int _n) {
        for (int i = 1; i <= _n; i++)
            lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
    }

    void dfs(int u, int f) {
        fa[u][0] = f;
        dep[u] = dep[f] + 1;
        for (int i = 1; i <= lg[dep[u]]; i++) fa[u][i] = fa[fa[u][i - 1]][i - 1];
        if (ch[u][0]) dfs(ch[u][0], u);
        if (ch[u][1]) dfs(ch[u][1], u);
    }

    int LCA(int u, int v) {
        if (dep[u] < dep[v]) swap(u, v);
        while (dep[u] > dep[v]) u = fa[u][lg[dep[u] - dep[v]] - 1];
        if (u == v) return u;
        for (int k = lg[dep[u]] - 1; k >= 0; k--) {
            if (fa[u][k] != fa[v][k]) u = fa[u][k], v = fa[v][k];
        }
        return fa[u][0];
    }

}

int dfs(int al, int ar, int bl, int br) {
    if (bl > br) return 0;
    if (al > ar) return 0;
    if (al == ar) return na[al];
    int ans = nb[bl];
    int len = (pos[ans] - al + 1);
    ch[ans][0] = dfs(al, pos[ans] - 1, bl + 1, bl + len - 1);
    ch[ans][1] = dfs(pos[ans] + 1, ar, bl + len, br);
    return ans;
}


int main() {
    int q, n;
    scanf("%d%d", &q, &n);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for (int i = 1; i <= n; i++) scanf("%d", &b[i]);

    for (int i = 1; i <= n; i++) {
        um1[a[i]] = i, um2[i] = a[i];
        na[i] = i;
    }

    for (int i = 1; i <= n; i++) {
        nb[i] = um1[b[i]];
    }

    for (int i = 1; i <= n; i++) pos[na[i]] = i;

    int root = dfs(1, n, 1, n);

    LCA::init(n);
    LCA::dfs(root, root);

    while (q--) {
        int u, v;
        scanf("%d%d", &u, &v);
        if (um1.find(u) == um1.end()) {
            if (um1.find(v) == um1.end()) printf("ERROR: %d and %d are not found.\n", u, v);
            else printf("ERROR: %d is not found.\n", u);
        } else if (um1.find(v) == um1.end()) printf("ERROR: %d is not found.\n", v);
        else {

            int uu = um1[u], vv = um1[v];
            int lca = LCA::LCA(uu, vv);
            if (uu == lca) printf("%d is an ancestor of %d.\n", u, v);
            else if (vv == lca) printf("%d is an ancestor of %d.\n", v, u);
            else printf("LCA of %d and %d is %d.\n", u, v, um2[lca]);
        }
    }

}
posted @ 2021-03-09 21:07  tudouuuuu  阅读(43)  评论(0编辑  收藏  举报