列表

详情


NC19055. Generator and Monitor

描述

You have a generator that randomly generates a uniformly distributed random number in range [1,m] and a monitor that monitors the generator and gives an alert when some conditions are met. If at the i-th second, a condition is given to the monitor, then the monitor will give an alert at the j-th second reporting that the condition given at the i-th second is met. Here j is the minimum integer such that the numbers generated by the generator from the i-th second to the j-th second and in range [li,ri] equals to ci. Otherwise, the generator will generate a number ai. However, the monitor stops working now. We need you to write a program to give the alerts. 

输入描述

The first line contains an integer T, the number of test cases.
For each test case, the first line contains an integer m and n. The following n lines describe events. The i-th line describe the event happens at the i-th second. If the event is to give a condition, then it contains a character ”C” followed by li, ri and ci. Otherwise, the event is to generate a number and it contains a character ”G” followed by bi. ai, the number generated at the i-th second equals to the XOR sum of bi and the moments of all conditions met before i-th second. 
It is guaranteed that 1 ≤ m ≤ 104 and 1 ≤ n ≤ 2×105

输出描述

For each test case, the output starts with a line ”Case #i:” where i is the test case number, starting from 1. Then you need to report the alerts in order. If some conditions are met at the i-th second, output a line containing i and moments when these conditions were given. Output moments in increasing order.

示例1

输入:

1
6 5
C 1 3 1
C 3 5 2
G 4
G 1
G 3
G 2

输出:

Case #1:
4 1
6 2

说明:

At the 1st second, a condition is given. We need to make an alert when 1 number in range [1, 3] are generated.

At the 2nd second, a condition is given. We need to make an alert when 2 number in range [3, 5] are generated.

At the 3rd second, a number is generated. It is 4 because no condition is met before. We don’t need to make any alert because no condition is met after 4 is generated.

At the 4th second, a number is generated. It is 1 because no condition is met before. We need to make an alert because condition at 1st second is met after 1 is generated.

At the 5th second, a number is generated. Because condition at the 1st second is met before, the actual number generated should be 3 xor 1 which is 2. We don’t need to make any alert because no condition is met after 2 is generated.

At the 6th second, a number is generated. Because condition at the 1st second is met before, the actual number generated should be 2 xor 1 which is 3. We need to make an alert because condition at the 2nd second is met after 3 is generated.

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 7015ms, 内存消耗: 18256K, 提交时间: 2018-10-07 13:30:28

#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 ;
} 

C++11(clang++ 3.9) 解法, 执行用时: 7394ms, 内存消耗: 18156K, 提交时间: 2018-10-07 16:01:18

#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 ;
}

上一题