关于树剖
  • 板块学术版
  • 楼主coolbreeze
  • 当前回复0
  • 已保存回复0
  • 发布时间2022/8/9 15:58
  • 上次更新2023/10/27 16:17:03
查看原帖
关于树剖
201219
coolbreeze楼主2022/8/9 15:58

改成多组数据之后在SPOJ那边出瓜了, 代码问题求调 (或者有没有可能...是P4114 Qtree1的数据弱了?)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int NN = 100020;
int T , N , M , S , cnt , tot;
int ax , by;
struct E{
	int from , to , nxt;
}e[ 2 * NN ];
int c[NN] , head[NN] , fa[NN] , dep[NN] , siz[NN] , hson[NN] , top[NN] ;
int dfn[NN] , rk[NN];//dfn表示节点对应的dfs序号,rk表示dfs序对应的节点编号。 
char cc[10];
int Sgm_maxTree[ NN << 2 ];
void fread( int &n ) {
	n = 0;
	int f = 1;
	char c = getchar();
	while( c < '0' || c > '9' ) {
		f = ( c == '-' ? -1 : 1 );
		c = getchar();
	}
	while( c >= '0' && c <= '9' ) {
		n = ( n << 1 ) + ( n << 3 ) + c - '0';
		c = getchar();	
	}
	return ;
}
void push_up( int t ) {
	Sgm_maxTree[t] = max( Sgm_maxTree[ t << 1 ] , Sgm_maxTree[ t << 1 | 1 ] );
	return ;
}
void build( int l , int r , int t ) {
	if( l == r ) {
		Sgm_maxTree[t] = c[ rk[l] ]; 
		return ;
	} 
	build( l , ( l + r ) >> 1 , t << 1 );
	build( ( ( l + r ) >> 1 ) + 1 , r , t << 1 | 1 );
	push_up(t);
	return ;	
}
void change( int ti , int to , int l , int r , int t ) {
	if( l == r ) {
		Sgm_maxTree[t] = ti;
		return ;
	}
	int mid = ( l + r ) >> 1;
	if( to <= mid ) 
		change( ti , to , l , mid , t *2 );
	else {
		
		change( ti , to , mid + 1 , r , t * 2 + 1 );
	}
	push_up(t);
}
int getmax( int L , int R , int l , int r , int t ) {
	if( r < L || l > R )
		return -1234567;
	if( L <= l && r <= R )
		return Sgm_maxTree[t];
	int ans = 0 , mid = ( l + r ) >> 1;
	if( L <= mid )
		ans = max( ans , getmax( L , R , l , mid , t * 2 ) );
	if( r > mid )
		ans = max( ans , getmax( L , R , mid + 1 , r , t * 2 + 1 ) );
	return ans;
}
inline void adde( int u , int v ) {
	e[ ++ cnt].nxt = head[u];
	e[ cnt ].from = u;
	e[ cnt ].to = v; 
	head[u] = cnt;
	return ;
}
void tree_inti( int x ) {
	siz[x] = 1;
	for( int i = head[x] ; i ; i = e[i].nxt ) {
		if( !dep[ e[i].to ] && e[i].to != fa[x] ) {
			dep[ e[i].to ] = dep[x] + 1;
			fa[ e[i].to ] = x;
			tree_inti( e[i].to );
			siz[x] += siz[ e[i].to ];
			if( siz[ e[i].to ] > siz[ hson[x] ] )
				hson[x] = e[i].to;
		}
	}
	return ;
}
void tree_decomposition( int x , int TOP ) {
	if( dfn[x] != 0 )
		return ;
	tot ++;
	dfn[x] = tot;
	rk[tot] = x;
	top[x] = TOP;//应初始化为节点本身 
	if( hson[x] ) //优先对重子节点DFS保证同一重链dfs序连续(if保证重子节点非叶节点) 
		tree_decomposition( hson[x] , TOP );//沿重子节点延伸重链 
	for( int i = head[x] ; i ; i = e[i].nxt ) //跨过轻边开新重链 
		if( e[i].to != fa[x] && e[i].to != hson[x] )
			tree_decomposition( e[i].to , e[i].to );
	return ;
}
int tree_query( int x , int y ) {
	int ans = 0;
	while( top[x] != top[y] ) {
		if( dep[ top[x] ] < dep[ top[y] ] )// 每次选择深度较大的链往上跳,直到两点在同一条链上。 
			swap( x , y );
		ans = max( ans  , getmax( dfn[ top[x] ] , dfn[x] , 1 , N , 1 ) );
		x = fa[ top[x] ];
	}
	if( dep[x] > dep[y] )
		swap( x , y );
	if( x != y )	
		ans = max( ans , getmax( dfn[x] + 1 , dfn[y] , 1 , N , 1 ) );
	return ans;
} 
inline void clean() {
	cnt = tot = 0;
	for( int i = 1 ; i <= N ; i ++ )
		c[i] = top[i] = head[i] = dep[i] = dfn[i] = fa[i] = hson[i] = siz[i] = rk[i] = 0;
	return ;
}
int main() {
	fread(T);
	for( int i = 1 ; i <= T ; i ++ ) {
		fread(N);
		clean();
		for( int i = 1 ; i <= N - 1 ; i ++ ) {
			fread(ax) , fread(by);
			fread( c[by] );
			adde( ax , by ) , adde( by , ax );
		}
		tree_inti(1);
		tree_decomposition( 1 , 1 );
		fa[1] = 1;
		build( 1 , N , 1 ); 
		while(1) {
			scanf("%s",cc);
			if( cc[0] == 'D' )
				break;
			fread(ax) , fread(by);
			if( cc[0] == 'Q' )
				printf("%d\n",tree_query( ax , by ) );
			else {
				int ni;
				if( dep[ e[ ax * 2 ].from ] > dep[ e[ ax * 2 ].to ] )
					ni = e[ ax * 2 ].from;
				else
					ni = e[ ax * 2 ].to;
				change( by , dfn[ ni ] , 1 , N , 1 );
			}
		}
	}
	return 0;
}
2022/8/9 15:58
加载中...