A: [CTSC2008] Network Management
This question was originally in the balanced tree section, but what I wrote was a tree set tree, and the balanced tree will have multiple log
questions.
Query kkk is big, the natural chairman tree can be maintained
There is no need to split the balanced tree, multiple log logL O G a
Put the tree (u, v) (u, v)( u ,v ) is converted touuu to root+ ++ vvv to root−-− l c a lca l c a to the root−-− l c a lca l c a father to root four parts
The chairman tree maintains all routers from each point to the root
Each modification of a single router will affect the entire subtree of that router
The entire subtree problem is transformed into dfn dfn on the treed f n order
Into a continuous interval
Maintain the prefix sum of the four parts with a tree array
So this question is a tree-like array set the chairman tree
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
#define maxn 80005
#define MAX 1e8
vector < int > G[maxn];
int n, Q, num;
int ti[maxn], dep[maxn], Start[maxn], End[maxn];
int sum[maxn * 300], lson[maxn * 300], rson[maxn * 300], root[maxn];//log^2±¶
int f[maxn][20];
int lowbit( int x ) {
return x & ( -x );
}
struct node {
int cnt, t[maxn];
int calc() {
int tot = 0;
for( int i = 1;i <= cnt;i ++ ) tot += sum[rson[t[i]]];
return tot;
}
void init( int x ) {
cnt = 0;
while( x ) t[++ cnt] = root[x], x -= lowbit( x );
}
void choose_l() {
for( int i = 1;i <= cnt;i ++ ) t[i] = lson[t[i]];
}
void choose_r() {
for( int i = 1;i <= cnt;i ++ ) t[i] = rson[t[i]];
}
}t1, t2, t3, t4;
void dfs( int u, int fa ) {
dep[u] = dep[fa] + 1, f[u][0] = fa, Start[u] = ++ num;
for( int i = 1;i < 18;i ++ )
f[u][i] = f[f[u][i - 1]][i - 1];
for( int i = 0;i < G[u].size();i ++ ) {
int v = G[u][i];
if( v == fa ) continue;
else dfs( v, u );
}
End[u] = num;
}
int LCA( int u, int v ) {
if( dep[u] < dep[v] ) swap( u, v );
for( int i = 17;~ i;i -- )
if( dep[f[u][i]] >= dep[v] )
u = f[u][i];
if( u == v ) return u;
for( int i = 17;~ i;i -- )
if( f[u][i] != f[v][i] )
u = f[u][i], v = f[v][i];
return f[u][0];
}
void modify( int &x, int l, int r, int pos, int v ) {
if( ! x ) x = ++ num;
sum[x] += v;
if( l == r ) return;
int mid = ( l + r ) >> 1;
if( pos <= mid ) modify( lson[x], l, mid, pos, v );
else modify( rson[x], mid + 1, r, pos, v );
}
void modify( int x, int pos, int c ) {
while( x <= n ) {
modify( root[x], 1, MAX, pos, c );
x += lowbit( x );
}
}
int query( int l, int r, int k ) {
if( l == r ) return l;
int mid = ( l + r ) >> 1;
int tot = t1.calc() + t2.calc() - t3.calc() - t4.calc();
if( tot >= k ) {
t1.choose_r(), t2.choose_r(), t3.choose_r(), t4.choose_r();
return query( mid + 1, r, k );
}
else {
t1.choose_l(), t2.choose_l(), t3.choose_l(), t4.choose_l();
return query( l, mid, k - tot );
}
}
int main() {
scanf( "%d %d", &n, &Q );
for( int i = 1;i <= n;i ++ )
scanf( "%d", &ti[i] );
for( int i = 1, u, v;i < n;i ++ ) {
scanf( "%d %d", &u, &v );
G[u].push_back( v );
G[v].push_back( u );
}
dfs( 1, 0 ); num = 0;
for( int i = 1;i <= n;i ++ )
modify( Start[i], ti[i], 1 ), modify( End[i] + 1, ti[i], -1 );
for( int i = 1, k, x, y;i <= Q;i ++ ) {
scanf( "%d %d %d", &k, &x, &y );
if( k ) {
int lca = LCA( x, y );
if( dep[x] + dep[y] - ( dep[lca] << 1 ) + 1 < k ) {
printf( "invalid request!\n" );
continue;
}
t1.init( Start[x] ), t2.init( Start[y] ), t3.init( Start[lca] ), t4.init( Start[f[lca][0]] );
printf( "%d\n", query( 1, MAX, k ) );
}
else {
modify( Start[x], ti[x], -1 ), modify( End[x] + 1, ti[x], 1 );
ti[x] = y;
modify( Start[x], ti[x], 1 ), modify( End[x] + 1, ti[x], -1 );
}
}
return 0;
}