CCCPaste

Untitled

#include 
#include 
#include 
#include 
using namespace std;

const int maxn = 3e5 + 10;
int n, LOG;
int id_node[maxn];
int parent[maxn];
int depth[maxn];
int query[maxn];
struct node {
    int idx, A, B;
    node () {}
    node(int _idx, int _A, int _B) {
        idx = _idx;
        A =_A;
        B = _B;
    }
};
int up_node[maxn][21];
void up_node_process() {
    memset(up_node, -1, sizeof up_node);
    for(int i = 0; i <= n; i++) {
        up_node[i][0] = parent[i];
    }
    for(int i = 0; i <= n; i++) {
        for(int j = 1; j < LOG; j++) {
            up_node[i][j] = up_node[ up_node[i][j - 1] ][j - 1];
        }
    }
}
int LCA(int A, int B) {
    if(depth[A] < depth[B]) {
        swap(A, B);
    }
    for(int i = LOG - 1; i >= 0; i--) {
        if(depth[A] - (1 << i) >= depth[B]) {
            A = up_node[A][i];
        }
    }
    if(A == B) {
        return A;
    }
    for(int i = LOG - 1; i >= 0; i--) {
        if(up_node[A][i] != -1 and up_node[A][i] != up_node[B][i]) {
            A = up_node[A][i];
            B = up_node[B][i];
        }
    }
    return up_node[A][0];
}
int main() {
    ios_base::sync_with_stdio(false);
    
    cin >> n;
    LOG = 0;
    while((1 << LOG) <= n) {
        LOG++;
    }
    memset(id_node, 0, sizeof id_node);
    memset(parent, -1, sizeof parent);
    memset(depth, 0, sizeof depth);
    memset(query, -1, sizeof query);
    parent[0] = 0;
    depth[0] = 0;
    
    
    vector to_LCA;
    for(int i = 1; i <= n; i++) {
        char c;
        cin >> c;
        
        if(c == 'a') {
            int A;
            cin >> A;
            
            A = id_node[A];
            id_node[i] = i;
            parent[i] = A;
            depth[i] = depth[parent[i]] + 1;
        }
        else if(c == 'b') {
            int A;
            cin >> A;
            A = id_node[A];
            id_node[i] = parent[A];
            query[i] = A;
        }
        else {
            int A, B;
            cin >> A >> B;
            A = id_node[A];
            B = id_node[B];
            id_node[i] = A;
            to_LCA.push_back(node(i, A, B));
        }
    }
    up_node_process();
    for(int i = 0; i < (int) to_LCA.size(); i++) {
        int A = to_LCA[i].A;
        int B = to_LCA[i].B;
        int lca = LCA(A, B);
        query[to_LCA[i].idx] = depth[lca];
    }
    for(int i = 1; i <= n; i++) {
        if(query[i] != -1) {
            cout << query[i] << endl;
        }
    }
 
    return 0;
}