求和
\(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 ;
}
$The \ light \ has \ betrayed \ me$

浙公网安备 33010602011771号