Topic link: https: //vjudge.net/contest/314922#problem/B
#include <cmath> #include <cstdio> #include <algorithm> #include <iostream> #include <cstring> #include <ctype.h> #include <map> #include <vector> #include <set> #include <bitset> #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r #define lc rt << 1 #define rc rt << 1 | 1 #define INF 0x7fffffff #define eps 1e-9 #define pi acos(-1.0) using namespace std; typedef long long ll; static const int MAX_N = 1e5 + 5; static const int Mod = 10007; struct Edge{ int to, next; }edge[MAX_N << 1]; int head[MAX_N]; //链式前向星 int siz[MAX_N], son[MAX_N], top[MAX_N], fa[MAX_N], tid[MAX_N], dep[MAX_N], pos[MAX_N]; int cnt, tot; void dfs1(int u, int f, int d){ //The first son of a weight dfs SIZ [U] = . 1 ; DEP [U] = D; Son [U] = 0 ; FA [U] = F; for ( int I = head [U];! = I - . 1 ; I = Edge [I] .next) { int V = Edge [I] .to; IF (V == F) Continue ; // do not take repeated passage DFS1 (V, U, D + . 1 ); SIZ [U ] + = SIZ [V]; IF (SIZ [V]> SIZ [Son [U]]) Son [U] = V; } } voidDFS2 ( int U, int T) { // the son ligation into a heavy chain, light son connected light chain (obtained interval) Top [U] = T; TID [U] = ++ CNT; POS [CNT] = U; IF (Son [U]) DFS2 (Son [U], T); // priority of the heavy chain for ( int I = head [U]; I = -! . 1 ; I = Edge [I] .next) { int V = Edge [I] .to; IF (!! V Son = [U] && V = FA [U]) DFS2 (V, V); } } int Tag [MAX_N << 2 ]; void prework ( ) { Memset ( head, -1, sizeof(head)); memset(tag, 0, sizeof(tag)); cnt = 0; tot = 0; } void addEdge(int u, int v){ edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } void pushUp(int rt){ tag[rt] = tag[lc] + tag[rc]; } void update(int rt, int l, int r, int pos){ if(l == r){ tag[rt] ^= 1; return ; } int mid = l + r >> 1; if(pos <= mid) update(lson, pos); else update(rson, pos); pushUp(rt); } int queryInd(int rt, int l, int r, int ql, int qr){ if(!tag[rt]) return -1; if(l == r) return pos[l]; int mid = l + r >> 1; int ans = -1; if(ql <= mid) ans = queryInd(lson, ql, qr); if(ans != -1) return ans; if(qr > mid) ans = queryInd(rson, ql, qr); return ans; } int queryPathInd(int u, int v){ int ans = -1, temp; while(top[u] != top[v]){ if(dep[top[u]] < dep[top[v]]) swap(u, v); temp = queryInd(1, 1, cnt, tid[top[u]], tid[u]); if(temp != -1) ans = temp; u = fa[top[u]]; } if(dep[u] > dep[v]) swap(u, v); temp = queryInd(1, 1, cnt, tid[u], tid[v]); //后面离的越近 if(temp != -1) ans = temp; return ans; } void mainwork(){ int n, q; scanf("%d%d", &n, &q); for(int i = 1; i < n; ++i){ int u, v; scanf("%d%d", &u, &v); addEdge(u, v); addEdge(v, u); } dfs1(1, 0, 1); dfs2(1, 1); while(q--){ int opt, x; scanf("%d%d", &opt, &x); if(opt) printf("%d\n", queryPathInd(1, x)); else update(1, 1, cnt, tid[x]); } } int main(){ // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); prework(); mainwork(); return 0; }