Loading

求和

\(Lca\)的板子,没啥可写的。

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
#define mp make_pair
#define R register int
#define int long 
#define printf Ruusupuu = printf

int Ruusupuu ;

using namespace std ;
typedef long long L ;
typedef long double D ;
typedef unsigned long long G ;
typedef pair< int , int > PI ;
const int N = 3e5 + 10 ;
const int M = 998244353 ;
const int K = 5e1 + 10 ;

inline int read(){
	int w = 0 ; bool fg = 0 ; char ch = getchar() ;
	while( ch < '0' || ch > '9' ) fg |= ( ch == '-' ) , ch = getchar() ;
	while( ch >= '0' && ch <= '9' ) w = ( w << 1 ) + ( w << 3 ) + ( ch ^ '0' ) , ch = getchar() ;
	return fg ? -w : w ; 
}

inline void wap( int &a , int &b ){ a = a ^ b , b = a ^ b , a = a ^ b ; }
inline int mins( int a , int b ){ int zt = b - a ; return a + ( zt & ( zt >> 31 ) ) ; }
inline int maxs( int a , int b ){ int zt = b - a ; return b - ( zt & ( zt >> 31 ) ) ; }
inline int abss( int a ){ int zt = a >> 31 ; return ( a + zt ) ^ zt ; }
inline int J( int a , int b ){ return a + b >= M ? a + b - M : a + b ; }
inline int S( int a , int b ){ return a - b < 0 ? a - b + M : a - b ; }
inline int T( int a , int b ){ return 1ll * a * b % M ; } 

int n , m , cnt , head [N] , d [N][K] , w [N][K] , fa [N][K] , x , y , k 	;  

struct E{ int fr , to , next ; } a [N] ;

inline void add( int f , int t ){
	a [++ cnt].fr = f ;
	a [cnt].to = t ; 
	a [cnt].next = head [f] ;
	head [f] = cnt ;
}

void sc(){
	n = read() ; memset( head , -1 , sizeof ( head ) ) ;
	for( R i = 1 ; i < n ; i ++ ) x = read() , y = read() , add( x , y ) ;
}

void dfs( int x ){
	for( R i = head [x] ; ~i ; i = a [i].next ){
		int y = a [i].to ;
		d [y][1] = d [x][1] + 1 ;
	//	printf( "%ld %ld\n" , x , y ) ;
		//if( y == 215125 || y == 46143 ) puts( "shit" ) ;
		for( R j = 1 ; j <= 50 ; j ++ ){
			d [y][j] = T( d [y][j - 1] , d [y][1] ) ;
			w [y][j] = J ( w [x][j] , d [y][j] ) ;
		}
		dfs( y ) ;
	}
}

void bfs(){
	queue< int > q ; q.push( 1 ) ;
	while( !q.empty() ){
		int x = q.front() ; q.pop() ;
		for( R i = head [x] ; ~i ; i = a [i].next ){
			int y = a [i].to ;
			fa [y][0] = x ;
			for( R j = 1 ; j <= 20 ; j ++ ) fa [y][j] = fa [fa [y][j - 1]][j - 1] ;
			q.push( y ) ;
		}
	}   
}

inline int Lca( int x , int y ){
	if( d [x][1] < d [y][1] ) wap( x , y ) ;
	//printf ( "%ld %ld\n" , d [x][1] , d [y][1] ) ;
	for( R i = 20 ; i >= 0 ; i -- ) 
		if( d [fa [x][i]][1] >= d [y][1] ) x = fa [x][i] ;
	//printf ( "%ld\n" , x ) ;	
	if( x == y ) return x ;
	for( R i = 20 ; i >= 0 ; i -- )
		if( fa [x][i] != fa [y][i] ) x = fa [x][i] , y = fa [y][i] ;
	//printf ( "%ld\n" , x ) ;
	return fa [x][0] ;
}

void work(){
	for( R i = 1 ; i <= n ; i ++ ) d [i][0] = 1 ;
	dfs( 1 ) ; bfs() ;
//	for( R i = 1 ; i <= n ; i ++ ) if( i != 1 && d [i][1] ) printf( "%ld\n" , i ) ;
	
	m = read() ;
	while( m -- ){
		x = read() , y = read() , k = read() ;
		int lca = Lca( x , y ) ;
		
			//printf ( "%ld %ld %ld\n" , lca , w [x][k] , w [y][k] ) ;	
			int ans = J( w [x][k] , w [y][k] ) ;
			ans = S( ans , T( w [lca][k] , 2 ) ) ;
			ans = J( ans , d [lca][k] ) ;
		
		printf( "%ld\n" , ans ) ;
	}
}

signed main(){	
	sc() ;
	work() ;
	return 0 ;
} 
posted @ 2021-06-27 20:57  Soresen  阅读(47)  评论(0)    收藏  举报