【HDU】5994 Generator and Monitor【KD树】

来源:互联网 发布:阿里云华南1 a b 区 编辑:程序博客网 时间:2024/06/06 00:46

题目链接:【HDU】5994 Generator and Monitor

看懂题就会做系列,模板题。

#include <bits/stdc++.h>using namespace std ;typedef long long LL ;#define clr( a , x ) memset ( a , x , sizeof a )const int MAXN = 200005 ;const int MAXM = 10000005 ;const int INF = 0x3f3f3f3f ;struct Node {    int p[2] ;    int f , l , r , idx ;    int Min[2] , Max[2] ;    int minv , v , pos ;    int addv ;    int operator [] ( const int idx ) const {        return p[idx] ;    }    void init () {        Min[0] = Max[0] = p[0] ;        Min[1] = Max[1] = p[1] ;        pos = minv = v = INF ;        addv = 0 ;    }    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] ) ;    }    void down ( int x ) {        if ( x ) minv += x , v += x , addv += x ;    }} ;struct Op {    int x , y , c ;} ;Op p[MAXN] ;char buf[MAXM + 1] , *cur = buf ;Node T[MAXN] ;int idx[MAXN] ;int root , cmpw , tot ;int res[MAXN] ;int n , m ;bool cmp ( const Node& a , const Node& b ) {    return a.p[cmpw] < b.p[cmpw] ;}int build ( int l , int r , int w , int f ) {    int o = l + r >> 1 ;    cmpw = w ;    nth_element ( T + l , T + o , T + r + 1 , cmp ) ;    idx[T[o].idx] = o ;    T[o].init () ;    T[o].f = f ;    T[o].l = l != o ? build ( l , o - 1 , !w , o ) : 0 ;    T[o].r = r != o ? build ( o + 1 , r , !w , o ) : 0 ;    if ( T[o].l ) T[o].up ( T[T[o].l] ) ;    if ( T[o].r ) T[o].up ( T[T[o].r] ) ;    return o ;}int check ( int x1 , int x2 , int y1 , int y2 , int x ) {    if ( x2 <= x && y1 >= x ) return 0 ;    if ( x1 <= x && y2 >= x ) return 2 ;    return 1 ;}void up ( int o ) {    T[o].minv = T[o].v ;    T[o].pos = T[o].idx ;    if ( T[o].l && T[T[o].l].minv < T[o].minv ) {        T[o].minv = T[T[o].l].minv ;        T[o].pos = T[T[o].l].pos ;    }    if ( T[o].r && T[T[o].r].minv < T[o].minv ) {        T[o].minv = T[T[o].r].minv ;        T[o].pos = T[T[o].r].pos ;    }}void down ( int o ) {    int x = T[o].addv ;    if ( !x ) return ;    if ( T[o].l ) T[T[o].l].down ( x ) ;    if ( T[o].r ) T[T[o].r].down ( x ) ;    T[o].addv = 0 ;}void sign_down ( int o ) {    if ( T[o].f ) sign_down ( T[o].f ) ;    down ( o ) ;}void upd ( int o , int x , int v ) {    int d = check ( T[o].Min[0] , T[o].Max[0] , T[o].Min[1] , T[o].Max[1] , x ) ;    if ( !d ) {        T[o].down ( v ) ;        return ;    }    if ( d == 1 ) return ;    if ( T[o][0] <= x && T[o][1] >= x ) {        T[o].v += v ;        T[o].minv += v ;    }    down ( o ) ;    if ( T[o].l ) upd ( T[o].l , x , v ) ;    if ( T[o].r ) upd ( T[o].r , x , v ) ;    up ( o ) ;}void add ( int o , int v ) {    for ( sign_down ( o ) , T[o].v = v ; o ; o = T[o].f ) up ( o ) ;}void scanf ( int& x ) {    while ( *cur < '0' ) ++ cur ;    x = *cur - '0' , ++ cur ;    while ( *cur >= '0' ) ( x *= 10 ) += *cur - '0' , ++ cur ;}void solve () {    tot = 0 ;    scanf ( n ) ;    scanf ( m ) ;    for ( int i = 1 ; i <= n ; ++ i ) {        char op ;        while ( ( op = *cur ) < 'A' ) ++ cur ;        ++ cur ;        if ( op == 'C' ) {            scanf ( p[i].x ) ;            scanf ( p[i].y ) ;            scanf ( p[i].c ) ;            ++ tot ;            T[tot].p[0] = p[i].x ;            T[tot].p[1] = p[i].y ;            T[tot].idx = i ;        } else p[i].c = 0 , scanf ( p[i].x ) ;    }    root = build ( 1 , tot , 0 , 0 ) ;    int now = 0 ;    for ( int i = 1 ; i <= n ; ++ i ) {        if ( p[i].c ) add ( idx[i] , p[i].c ) ;        else upd ( root , p[i].x ^ now , -1 ) ;        int val = 0 , top = 0 ;        while ( !T[root].minv ) {            val ^= T[root].pos ;            res[++ top] = T[root].pos ;            add ( idx[T[root].pos] , INF ) ;        }        now ^= val ;        if ( top ) {            printf ( "%d" , i ) ;            sort ( res + 1 , res + top + 1 ) ;            for ( int j = 1 ; j <= top ; ++ j ) {                printf ( " %d" , res[j] ) ;            }            puts ( "" ) ;        }    }}int main () {    fread ( buf , 1 , MAXM , stdin ) ;    int T ;    scanf ( T ) ;    for ( int i = 1 ; i <= T ; ++ i ) {        printf ( "Case #%d:\n" , i ) ;        solve () ;    }    return 0 ;}
0 0