蒟蒻刚学点分树,只过hack求调
查看原帖
蒟蒻刚学点分树,只过hack求调
683859
complete_binary_tree楼主2024/4/3 23:19

rt,只过样例和hack,#10tle(应该是倍增lca的问题),#8re,其他全wa求调。

#include<bits/stdc++.h>
using namespace std;

namespace FastIO{
template<typename T>
	void read(T& x);

	template<typename T, typename ... Args>
	void read(T& a, Args& ...b){
		read(a), read(b...);
	}

	template<typename T>
	void read(T& x){
		x = 0;int f = 1;
		char ch = getchar();
		while((ch < '0' || ch > '9') && ch != EOF){
			if(ch == '-') f = -1;
			ch = getchar();
		}
		while(ch >= '0' && ch <= '9'){
			x = x * 10 + ch - 48;
			ch = getchar();
		}
		x *= f;
		return ;
	}
};
using FastIO::read;

const int N = 100005;

int n;
struct node{ int to, nxt; };

struct lianshi{
	int head[N];
	node e[N << 1];
	int cnt;
	void add( int u, int v ){ e[++cnt] = { v, head[u] }; head[u] = cnt; }
	operator node*(){ return e; }
} tree;

int fa[20][N], deep[N];

void dfs1( int u, int _fa ){ //初始化:fa,deep
	fa[0][u] = _fa, deep[u] = deep[_fa] + 1;
	for( int i = tree.head[u]; i; i = tree[i].nxt ){
		int v = tree[i].to;
		if( v == _fa ) continue;
		dfs1( v, u );
	}
	return ;
}

void prelca(){ //lca的预处理
	for( int i = 1; i <= 18; ++i )
		for( int j = 1; j <= n; ++j )
			fa[i][j] = fa[i - 1][fa[i - 1][j]];
}

int jumpup( int a, int num ){
	int i = 0;
	while( num ){
		if( num & 1 ) a = fa[i][a];
		num >>= 1, ++i;
	}
	return a;
}

int lca( int a, int b ){
	if( a == b ) return a;
	if( deep[a] > deep[b] ) swap( a, b );
	b = jumpup( b, deep[b] - deep[a] );
	if( a == b ) return a;
	for( int i = 18; i >= 0; --i ){
		if( fa[i][a] != fa[i][b] ) a = fa[i][a], b = fa[i][b];
	}
	return fa[0][a];
}
int dist( int a, int b ){
	int _lca = lca( a, b );
	return deep[a] + deep[b] - 2 * deep[_lca];
}

bool vis[N];
int fadft[N], nodft[N], jds[N], mxzs[N];
queue<int> q;

void findzx( int u, int _fa ){
	jds[u] = 1, mxzs[u] = 0;
	q.push( u );
	for( int i = tree.head[u]; i; i = tree[i].nxt ){
		int v = tree[i].to;
		if( vis[v] || v == _fa ) continue;
		findzx( v, u );
		jds[u] += jds[v], mxzs[u] = max( mxzs[u], jds[v] );
	}
	return ;
}

vector<int> dft[N];

int dfz( int root, int _fa ){ //建造点分树
	findzx( root, 0 );
	int jd = jds[root];
	while( !q.empty() ){
		int u = q.front(); q.pop();
		mxzs[u] = max( mxzs[u], jd - jds[u] );
		if( mxzs[root] > mxzs[u] ) root = u;
	}
	vis[root] = 1;
	for( int i = tree.head[root]; i; i = tree[i].nxt ){
		int v = tree[i].to;
		if( v == _fa || vis[v] ) continue;
		int sonroot = dfz( v, root );
		dft[root].push_back( sonroot );
		fadft[sonroot] = root;
		nodft[sonroot] = dft[root].size() - 1;
	}
	return root;
}

int root, cnt, kd[N];
set<pair<int, int>> st[N]; //son,dis
set<pair<int, int>> st2[N]; //u,dis
bool deng[N];

void change( int pos ){
	if( !deng[pos] ){
		deng[pos] = 1;
		cnt++;
		for( int i = pos; i; i = fadft[i] ){
//			printf("!%d\n", i);
			if( kd[i] ) st[fadft[i]].erase( make_pair( ( *( --st2[i].end() ) ).first, nodft[i] ) );
			st2[i].insert( make_pair( dist( pos, i ), pos ) );
			st[fadft[i]].insert( make_pair( dist( pos, fadft[i] ), nodft[i] ) );
			kd[i]++;
		}
	}
	else{
		deng[pos] = 0;
		cnt--;
		for( int i = pos; i; i = fadft[i] ){
//			printf("!%d", i);
			st2[i].erase( make_pair( dist( pos, i ), pos ) );
			st[fadft[i]].erase( make_pair( dist( pos, fadft[i] ), nodft[i] ) );
			kd[i]--;
			if( kd[i] ) st[fadft[i]].insert( make_pair( ( *( --st2[i].end() ) ).first, fadft[i] ) );
		}
	}
}

//int root;

int query(){
	int ans = 0;
	if( cnt <= 0 ) return -1;
	if( cnt == 1 ) return 0;
	for( int i = root; i; ){
//		printf("!%d\n", i);
		if( st[i].size() == 0 ) break;
		if( st[i].size() == 1 ){
			if( deng[i] ) ans = max( ans, (*st[i].begin()).first );
			i = dft[i][(*st[i].begin()).second];
			continue;
		}
		auto _end = --st[i].end();
		ans = max( ans, (*_end).first + (*(--_end)).first );
//		_end = --st[i].end();
//		printf("-%d %d\n", (*_end).first, (*(--_end)).first);
		i = dft[i][(*(--st[i].end())).second];
	}
	return ans;
}

int qu;


int main(){
	read( n );
	for( int i = 1; i < n; ++i ){
		int u, v;
		read( u, v );
		tree.add( u, v ), tree.add( v, u );
	}
	dfs1( 1, 0 );
	prelca();
	root = dfz( 1, 0 );
	for( int i = 1; i <= n; ++i ) change( i );
	read( qu );
	while( qu-- ){
		char ch;
		cin >> ch;
		if( ch == 'G' ) printf( "%d\n", query() );
		else{
			int x;
			read( x );
			change( x );
		}
	}
	return 0;
}
/*
8
1 2
2 3
3 4
3 5
3 6
6 7
6 8
7
G
C 1
G
C 2
G
C 1
G
*/
2024/4/3 23:19
加载中...