1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
| const int maxn = 3e5 + 5; const int maxlg = 20;
struct Dir { int len, son, far; } dir[maxn][3];
vector<int> adj[maxn]; int up[maxn][maxlg], dep[maxn];
void add( int u, Dir cur ) { for( int j = 0; j < 3; ++ j ) { if( cur.len > dir[u][j].len ) { swap( cur, dir[u][j] ); } } }
void dfs1( int u, int p ) { up[u][0] = p, dep[u] = dep[p] + 1; for( int i = 1; i < maxlg; ++ i ) { int mid = up[u][i-1]; up[u][i] = up[mid][i-1]; } dir[u][0] = { 0, 0, u }; dir[u][1] = { 0, 0, u }; dir[u][2] = { 0, 0, u }; for( int v : adj[u] ) { if( v == p ) continue; dfs1( v, u ); add( u, { dir[v][0].len + 1, v, dir[v][0].far } ); } }
void dfs2( int u, int p ) { for( int v : adj[u] ) { if( v == p ) continue; int k = ( dir[u][0].son == v ? 1 : 0 ); add( v, { dir[u][k].len + 1, u, dir[u][k].far } ); dfs2( v, u ); } }
struct Node { int val, pos; bool operator < ( const Node oth ) const { return val > oth.val; } };
struct State { int d1, d2, d3, id; bool operator < ( const State oth ) const { return d1 > oth.d1; } } ps[maxn];
struct Query { Node A, B, C; int id; bool operator < ( const Query oth ) const { return A < oth.A; } } qs[maxn];
struct BIT {
Node tr[maxn]; int sz; void init( int N ) { sz = N + 1; fill( tr, tr + sz + 1, Node{ -1, 0 } ); } void add( int idx, Node cur ) { idx ++; for( int i = idx; i; i -= i & -i ) { if( cur.val > tr[i].val ) tr[i] = cur; } } Node ask( int idx ) { idx ++; Node res = { -1, 0 }; for( int i = idx; i <= sz; i += i & -i ) { if( tr[i].val > res.val ) res = tr[i]; } return res; }
} bit;
int jump( int u, int k ) { for( int i = 0; i < maxlg; ++ i ) { if( ( k >> i ) & 1 ) u = up[u][i]; } return u; }
int get_lca( int u, int v ) { if( dep[u] < dep[v] ) swap( u, v ); u = jump( u, dep[u] - dep[v] ); if( u == v ) return u; for( int i = maxlg - 1; i >= 0; -- i ) { if( up[u][i] == up[v][i] ) continue; u = up[u][i], v = up[v][i]; } return up[u][0]; }
int movek( int u, int v, int k ) { int lca = get_lca( u, v ); int du = dep[u] - dep[lca]; int dv = dep[v] - dep[lca]; if( k <= du ) return jump( u, k ); else return jump( v, dv - ( k - du ) ); }
int ans[maxn][3];
void solve( ) { int n = read( ); for( int i = 1; i < n; ++ i ) { int u = read( ), v = read( ); adj[u].push_back( v ); adj[v].push_back( u ); }
dfs1( 1, 0 ); dfs2( 1, 0 );
for( int i = 1; i <= n; ++ i ) { ps[i].d1 = dir[i][0].len; ps[i].d2 = dir[i][1].len; ps[i].d3 = dir[i][2].len; ps[i].id = i; } sort( ps + 1, ps + n + 1 );
int Q = read( ); for( int i = 1; i <= Q; ++ i ) { int x = read( ), y = read( ), z = read( ); int a = ( x + y - z ) / 2; int b = ( x + z - y ) / 2; int c = ( y + z - x ) / 2; Node tmp[3] = { { a, 0 }, { b, 1 }, { c, 2 } }; sort( tmp, tmp + 3 ); qs[i] = { tmp[0], tmp[1], tmp[2], i }; } sort( qs + 1, qs + Q + 1 );
bit.init( n ); int i = 1; for( int j = 1; j <= Q; ++ j ) { auto [A, B, C, idx] = qs[j]; while( i <= n && ps[i].d1 >= A.val ) { bit.add( ps[i].d2, { ps[i].d3, ps[i].id }); i ++; } Node res = bit.ask( B.val ); int u = res.pos; Dir d1 = dir[u][0], d2 = dir[u][1], d3 = dir[u][2]; ans[idx][A.pos] = movek( d1.far, u, d1.len - A.val ); ans[idx][B.pos] = movek( d2.far, u, d2.len - B.val ); ans[idx][C.pos] = movek( d3.far, u, d3.len - C.val ); }
for( int i = 1; i <= Q; ++ i ) { cout << ans[i][0] << " " << ans[i][1] << " " << ans[i][2] << '\n'; } }
|