[Tree Set Tree] Network Management

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;
}

Guess you like

Origin blog.csdn.net/Emm_Titan/article/details/114952215