【HDU】5039 Hilarity 线段树

来源:互联网 发布:阿里巴巴菜鸟网络面试 编辑:程序博客网 时间:2024/05/17 10:41

传送门:【HDU】5039 Hilarity


题目分析:u->v的路径可以看成1->u的路径和1->v的路径异或出来的,所以题目要求等效于求ans =(值为1的边数*值为0的边数+从根出发的异或为1的路径)* 2。

首先以1为根(处理线段树方便),处理出树的dfs时间戳,以此将这棵树投影到线段上,则这棵树某个点的子树即他的时间戳内的所有点。我们用边上深度大的点作为这条边的代号,然后因为每次改变一条边的时候根到子树上的边的值全会发生改变,所以我们要改变根到这条边的子树上的所有边的值!这个用区间异或即可。然后这题就成了简单的区间修改问题了。


代码如下:


#include <cstdio>#include <cstring>#include <algorithm>#include <string>#include <map>using namespace std ;typedef long long LL ;#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 travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )#define clr( a , x ) memset ( a , x , sizeof a )#define CPY( a , x ) memcpy ( a , x , sizeof a )#define ls ( o << 1 )#define rs ( o << 1 | 1 )#define lson ls , l , m#define rson rs , m + 1 , r#define rt o , l , r#define root 1 , 2 , n#define mid ( ( l + r ) >> 1 )const int MAXN = 30005 ;const int MAXE = 60005 ;struct Edge {int v , idx ;Edge* next ;} E[MAXE] , *H[MAXN] , *edge ;int idx[MAXN] ;map < string , int > mp  ;int point ;int sum[MAXN << 2] ;bool lazy[MAXN << 2] ;int cost[MAXN] ;char buf[11] ;int in[MAXN] , ou[MAXN] , dfs_clock ;int n , q ;void clear () {edge = E ;point = 1 ;mp.clear () ;dfs_clock = 0 ;clr ( H , 0 ) ;clr ( sum , 0 ) ;clr ( lazy , 0 ) ;}void addedge ( int u , int v , int idx ) {edge -> v = v ;edge -> idx = idx ;edge -> next = H[u] ;H[u] = edge ++ ;}int read () {scanf ( "%s" , buf ) ;map < string , int > :: iterator it = mp.find ( buf ) ;if ( it != mp.end () ) return it -> second ;mp.insert ( map < string , int > :: value_type ( buf , point ) ) ;return point ++ ;}void pushup ( int o ) {sum[o] = sum[ls] + sum[rs] ;}void pushdown ( int o , int l , int r ) {if ( lazy[o] ) {lazy[ls] ^= 1 ;lazy[rs] ^= 1 ;int m = mid ;sum[ls] = m - l + 1 - sum[ls] ;sum[rs] = r - m - sum[rs] ;lazy[o] = 0 ;}}void update ( int L , int R , int o , int l , int r ) {if ( L <= l && r <= R ) {sum[o] = r - l + 1 - sum[o] ;lazy[o] ^= 1 ;return ;}int m = mid ;pushdown ( rt ) ;if ( L <= m ) update ( L , R , lson ) ;if ( m <  R ) update ( L , R , rson ) ;pushup ( o ) ;}void dfs ( int u , int fa = 0 , int d = 0 ) {in[u] = ++ dfs_clock ;if ( d ) update ( in[u] , in[u] , root ) ;travel ( e , H , u ) {int v = e -> v ;if ( v != fa ) {idx[e -> idx] = v ;dfs ( v , u , d ^ cost[e -> idx] ) ;}}ou[u] = dfs_clock ;}void build ( int o , int l , int r ) {if ( l == r ) {sum[o] = cost[re_idx[l]] ;return ;}int m = mid ;build ( lson ) ;build ( rson ) ;pushup ( o ) ;}void solve () {int u , v , c ;clear () ;scanf ( "%d" , &n ) ;rep ( i , 0 , n ) read () ;rep ( i , 1 , n ) {u = read () ;v = read () ;scanf ( "%d" , &cost[i] ) ;addedge ( u , v , i ) ;addedge ( v , u , i ) ;}dfs ( 1 ) ;//build ( root ) ;scanf ( "%d" , &q ) ;while ( q -- ) {scanf ( "%s" , buf ) ;if ( buf[0] == 'Q' ) printf ( "%d\n" , 2 * sum[1] * ( ( n - 1 - sum[1] ) + 1 ) ) ;else {scanf ( "%d" , &c ) ;update ( in[idx[c]] , ou[idx[c]] , root ) ;//printf ( "....%d\n" , sum[1] ) ;}}}int main () {int T , cas = 0 ;scanf ( "%d" , &T ) ;while ( T -- ) {printf ( "Case #%d:\n" , ++ cas ) ;solve () ;}return 0 ;}


0 0
原创粉丝点击