CCCPaste

Untitled

#include 
#include 
using namespace std;

const int maxn = 1e6 + 10;
vector graph[maxn];
int in_time[maxn], out_time[maxn];
int up_node[maxn][25];

int timer, LOG, n;
void dfs(int node, int parent) {
    in_time[node] = ++timer;
    up_node[node][0] = parent;
    
    for(int i = 1; i <= LOG; i++) {
        up_node[node][i] = up_node[ up_node[node][i - 1] ][i - 1];
    }
    
    for(int i = 0; i < (int) graph[node].size(); i++) {
        int neighbour = graph[node][i];
        if(parent != neighbour) {
            dfs(neighbour, node);
        }
    }
    out_time[node] = ++timer;
}
bool is_ancestor(int A, int B) {
    return in_time[A] <= in_time[B] and out_time[A] >= out_time[B];
}
int LCA(int A, int B) {
    if(is_ancestor(A, B)) {
        return A;
    }
    if(is_ancestor(B, A)) {
        return B;
    }
    for(int i = LOG; i >= 0; i--) {
        if(!is_ancestor(up_node[A][i], B)) {
            A = up_node[A][i];
        }
    }
    return up_node[A][0];
}
void preprocess() {
    timer = 0;
    LOG = 0;
    while((1 << LOG) <= n) {
        LOG++;
    }
    dfs(0, -1);
}
int main() {
    ios_base::sync_with_stdio(false);
    
    cin >> n;
    
    for(int i = 1; i < n; i++) {
        int a, b;
        cin >> a >> b;
        a--; b--;
        graph[a].push_back(b);
        graph[b].push_back(a);
    }
    preprocess();
    
    int q;
    cin >> q;
    for(int i = 0; i < q; i++) {
        int a, b;
        cin >> a >> b;
        a--; b--;
        cout << LCA(a, b) << endl;
    }
    return 0;
}