P10113 [GESP202312 八级] 大量的工作沟通 题解

· · 题解

题目传送门

好像没有用欧拉序做的题解( ?)

题意

思路

算法介绍

一些问题

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
vector<int> adj[maxn];// vector邻接表存图
int dep[maxn],dfn[maxn<<1],l[maxn],gr[maxn],cnt; 
// gr表示本节点到根节点经过的节点的最大编号
//  其他数组含义如上述
int lg2[maxn<<1],st[maxn<<1][25];
void dfs(int cu,int pr) {
    dfn[++cnt]=cu;
    l[cu]=cnt;
    dep[cu]=dep[pr]+1;
    gr[cu]=max(cu,gr[pr]);
    for(int to:adj[cu]) {
        dfs(to,cu);
        dfn[++cnt]=cu;
    }
}
void init(){ // ST表初始化 + 线性求log
    lg2[0]=-1;
    for(int i=1;i<=cnt;++i) {
        st[i][0]=dfn[i]; 
        lg2[i]=lg2[i>>1]+1;
    }
    for(int i=1;i<=lg2[cnt];++i) {
        for(int j=1;i<=lg2[cnt-j+1];++j){
            st[j][i]=dep[st[j][i-1]]<dep[st[j+(1<<(i-1))][i-1]]?
                         st[j][i-1] :    st[j+(1<<(i-1))][i-1];
        }
    }
}
void query(int n){
    int lca;
    scanf("%d",&lca);
    while(--n) {
        int x;
        scanf("%d",&x);
        if(l[lca]<l[x]) lca^=x^=lca^=x; // 异或交换两个元素,等价于swap()
        int k=lg2[(l[lca]-l[x]+1)];
        lca=dep[st[l[x]][k]]<dep[st[l[lca]-(1<<k)+1][k]]?
                st[l[x]][k] :    st[l[lca]-(1<<k)+1][k]; // O(1)查询lca
    }
    printf("%d\n",gr[lca]);
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1,x;i<n;++i){
        scanf("%d",&x);
        adj[x].push_back(i);
    }
    dfs(0,0);
    init();
    int m;
    scanf("%d",&m);
    while(m--) {
        scanf("%d",&n);
        query(n); // 回答本次询问
    }
    return 0;
}

第一次写题解,不足之处望海涵