传送门:3572: [Hnoi2014]世界树
my code:
#include <stdio.h> #include <string.h> #include <set> #include <algorithm> using namespace std ; typedef long long LL ; typedef unsigned long long ULL ; typedef pair < int , int > pii ; #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define clr( a , x ) memset ( a , x , sizeof a ) #define mp make_pair #define st first #define ed second const int MAXN = 300005 ; const int MAXE = 600005 ; const int LOG = 20 ; const int INF = 0x3f3f3f3f ; struct Edge { int v , n ; Edge () {} Edge ( int v , int n ) : v ( v ) , n ( n ) {} } ; Edge E[MAXE] ; int H[MAXN] , cntE ; int idx[MAXN] , dfs_clock ; int S[MAXN] , top ; int f[MAXN][LOG] ; int tree[MAXN] ; int node[MAXN] ; int dep[MAXN] ; int siz[MAXN] ; int dis[MAXN] ; int val[MAXN] ; int ans[MAXN] ; int fa[MAXN] ; pii G[MAXN] ; int n , m ; void init () { cntE = 0 ; dfs_clock = 0 ; clr ( H , -1 ) ; } void addedge ( int u , int v ) { E[cntE] = Edge ( v , H[u] ) ; H[u] = cntE ++ ; } void dfs ( int u ) { idx[u] = ++ dfs_clock ; siz[u] = 1 ; for ( int i = H[u] ; ~i ; i = E[i].n ) { int v = E[i].v ; if ( v == f[u][0] ) continue ; f[v][0] = u ; dep[v] = dep[u] + 1 ; rep ( j , 1 , LOG ) f[v][j] = f[f[v][j - 1]][j - 1] ; dfs ( v ) ; siz[u] += siz[v] ; } } int find ( int x , int depth ) { rev ( i , LOG - 1 , 0 ) if ( dep[x] - ( 1 << i ) >= depth ) x = f[x][i] ; return x ; } int get_lca ( int x , int y ) { if ( dep[x] < dep[y] ) swap ( x , y ) ; x = find ( x , dep[y] ) ; if ( x == y ) return x ; rev ( i , LOG - 1 , 0 ) if ( f[x][i] != f[y][i] ) { x = f[x][i] ; y = f[y][i] ; } return f[x][0] ; } void read_graph () { int u , v ; rep ( i , 1 , n ) { scanf ( "%d%d" , &u , &v ) ; addedge ( u , v ) ; addedge ( v , u ) ; } } bool cmp ( const int& x , const int& y ) { return idx[x] < idx[y] ; } void deal () { int cnt , tot ; scanf ( "%d" , &cnt ) ; rep ( i , 0 , cnt ) { scanf ( "%d" , &node[i] ) ; tree[i] = node[i] ; ans[node[i]] = 0 ; G[node[i]] = mp ( 0 , node[i] ) ; } tot = cnt ; sort ( tree , tree + cnt , cmp ) ; S[top = 1] = tree[0] ; fa[tree[0]] = 0 ; rep ( i , 1 , cnt ) { int tmp = tree[i] , lca = get_lca ( S[top] , tmp ) ; fa[tmp] = lca ; while ( top && dep[lca] < dep[S[top]] ) { if ( dep[S[top - 1]] <= dep[lca] ) fa[S[top]] = lca ; -- top ; } if ( S[top] != lca ) { fa[lca] = S[top] ; S[++ top] = lca ; tree[tot ++] = lca ; G[lca] = mp ( INF , 0 ) ; } S[++ top] = tmp ; } sort ( tree , tree + tot , cmp ) ; rep ( i , 0 , tot ) { int t = tree[i] , p = fa[t] ; val[t] = siz[t] ; dis[t] = dep[t] - dep[p] ; } rev ( i , tot - 1 , 1 ) { int t = tree[i] , p = fa[t] ; G[p] = min ( G[p] , mp ( G[t].st + dis[t] , G[t].ed ) ) ; } rep ( i , 1 , tot - 1 ) { int t = tree[i] , p = fa[t] ; G[t] = min ( G[t] , mp ( G[p].st + dis[t] , G[p].ed ) ) ; } rev ( i , tot - 1 , 0 ) { int t = tree[i] , p = fa[t] , x = find ( t , dep[p] + 1 ) , sum = siz[x] - siz[t] ; ans[G[t].ed] += val[t] ; if ( !i ) { ans[G[t].ed] += n - siz[t] ; continue ; } val[p] -= siz[x] ; if ( G[p].ed == G[t].ed ) ans[G[t].ed] += sum ; else { int d = G[t].st + G[p].st + dis[t] - 1 ; int mid = dep[t] - ( d / 2 - G[t].st ) + ( d % 2 == 1 && G[t].ed < G[p].ed ? -1 : 0 ) ; int y = siz[find ( t , mid )] - siz[t] ; ans[G[t].ed] += y ; ans[G[p].ed] += sum - y ; } } rep ( i , 0 , cnt ) printf ( "%d " , ans[node[i]] ) ; printf ( "\n" ) ; } void solve () { init () ; read_graph () ; dfs ( 1 ) ; scanf ( "%d" , &m ) ; rep ( i , 0 , m ) deal () ; } int main () { while ( ~scanf ( "%d" , &n ) ) solve () ; return 0 ; }