【BZOJ】4154: [Ipsc2015]Generating Synergy【KD树】

来源:互联网 发布:粗花呢西装 知乎 编辑:程序博客网 时间:2024/06/05 13:32

传送门:【BZOJ】4154: [Ipsc2015]Generating Synergy

分析:以dfs序和深度为关键字,作为平面点,于是对于每个询问就是在平面上的矩形区域修改以及查询。

my   code:

#include <bits/stdc++.h>using namespace std ;typedef long long LL ;#define clr( a , x ) memset ( a , x , sizeof a )const int MAXN = 100005 ;const int mod = 1e9 + 7 ;struct Edge {    int v , n ;    Edge () {}    Edge ( int v , int n ) : v ( v ) , n ( n ) {}} ;struct Node {    int p[2] ;    int f , l , r ;    int Min[2] , Max[2] ;    int tim , col ;    int t , c ;    int operator [] ( const int idx ) const {        return p[idx] ;    }    void up ( Node& a ) {        Min[0] = min ( Min[0] , a.Min[0] ) ;        Max[0] = max ( Max[0] , a.Max[0] ) ;        Min[1] = min ( Min[1] , a.Min[1] ) ;        Max[1] = max ( Max[1] , a.Max[1] ) ;    }} ;Node T[MAXN] ;Edge E[MAXN] ;int H[MAXN] , cntE ;int idx[MAXN] , cmpw , root ;int in[MAXN] , ou[MAXN] , dfs_clock ;int dep[MAXN] ;int n , q ;void addedge ( int u , int v ) {    E[cntE] = Edge ( v , H[u] ) ;    H[u] = cntE ++ ;}void dfs ( int u ) {    in[u] = ++ dfs_clock ;    for ( int i = H[u] ; ~i ; i = E[i].n ) {        int v = E[i].v ;        dep[v] = dep[u] + 1 ;        dfs ( v ) ;    }    ou[u] = ++ dfs_clock ;}bool cmp ( const Node& a , const Node& b ) {    return a[cmpw] < b[cmpw] ;}void up ( int o ) {    if ( T[o].l ) T[o].up ( T[T[o].l] ) ;    if ( T[o].r ) T[o].up ( T[T[o].r] ) ;}int build ( int l , int r , int w , int f ) {    int mid = l + r >> 1 ;    cmpw = w ;    nth_element ( T + l , T + mid , T + r + 1 , cmp ) ;    idx[T[mid].f] = mid ;    T[mid].f = f ;    T[mid].Min[0] = T[mid].Max[0] = T[mid][0] ;    T[mid].Min[1] = T[mid].Max[1] = T[mid][1] ;    T[mid].l = l != mid ? build ( l , mid - 1 , !w , mid ) : 0 ;    T[mid].r = r != mid ? build ( mid + 1 , r , !w , mid ) : 0 ;    up ( mid ) ;    return mid ;}void upd ( int o , int t , int c , int x1 , int x2 , int y1 , int y2 ) {    if ( T[o].Min[0] >= x1 && T[o].Max[0] <= x2 && T[o].Min[1] >= y1 && T[o].Max[1] <= y2 ) {        T[o].tim = T[o].t = t ;        T[o].col = T[o].c = c ;        return ;    }    if ( T[o].Min[0] > x2 || T[o].Max[0] < x1 || T[o].Min[1] > y2 || T[o].Max[1] < y1 ) return ;    if ( T[o][0] >= x1 && T[o][0] <= x2 && T[o][1] >= y1 && T[o][1] <= y2 ) {        T[o].tim = t ;        T[o].col = c ;    }    if ( T[o].l ) upd ( T[o].l , t , c , x1 , x2 , y1 , y2 ) ;    if ( T[o].r ) upd ( T[o].r , t , c , x1 , x2 , y1 , y2 ) ;}int query ( int o ) {    int t = T[o].tim , c = T[o].col ;    while ( T[o].f ) {        o = T[o].f ;        if ( T[o].t > t ) {            t = T[o].t ;            c = T[o].c ;        }    }    return c ;}void solve () {    int x , l , c ;    scanf ( "%d%*d%d" , &n , &q ) ;    cntE = dfs_clock = 0 ;    clr ( H , -1 ) ;    for ( int i = 2 ; i <= n ; ++ i ) {        scanf ( "%d" , &x ) ;        addedge ( x , i ) ;    }    dfs ( 1 ) ;    T[0].tim = T[0].t = 0 ;    T[0].col = T[0].c = 1 ;    for ( int i = 1 ; i <= n ; ++ i ) {        T[i].p[0] = in[i] ;        T[i].p[1] = dep[i] ;        T[i].col = T[i].c = 1 ;        T[i].tim = T[i].t = 0 ;        T[i].f = i ;    }    root = build ( 1 , n , 0 , 0 ) ;    int ans = 0 ;    for ( int i = 1 ; i <= q ; ++ i ) {        scanf ( "%d%d%d" , &x , &l , &c ) ;        if ( c ) {            if ( l == 0 || in[x] == ou[x] ) {                T[idx[x]].tim = i ;                T[idx[x]].col = c ;                continue ;            }            upd ( root , i , c , in[x] , ou[x] , dep[x] , dep[x] + l ) ;        } else {            int tmp = query ( idx[x] ) ;            ans = ( ans + 1LL * i * tmp ) % mod ;        }    }    printf ( "%d\n" , ans ) ;}int main () {    int T ;    scanf ( "%d" , &T ) ;    for ( int i = 1 ; i <= T ; ++ i ) {        solve () ;    }    return 0 ;}
0 0
原创粉丝点击