题目分析:将X轴离散化,然后构造一棵线段树,线段树的每个叶子节点维护一个set,里面为坐标为a[x]的点的y坐标的集合。线段树维护区间内所有点能达到的y的最大值。
每次插入删除就单点更新,询问的时候看区间【x+1,cnt】内maxv[ o ]是否大于y,不存在返回0,否则返回最左边满足集合内存在y坐标大于查询的值的下标。然后在下标所在的集合查询最小的大于y的y'值即可。
set真是强大!
代码如下:
#include <set>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
typedef long long LL ;
#define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )
#define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i )
#define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define clr( a , x ) memset ( a , x , sizeof a )
#define cpy( a , x ) memcpy ( a , x , sizeof a )
#define mid ( ( l + r ) >> 1 )
#define ls ( o << 1 )
#define rs ( o << 1 | 1 )
#define lson ls , l , m
#define rson rs , m + 1 , r
#define root 1 , 1 , cnt
#define rt o , l , r
#define mid ( ( l + r ) >> 1 )
const int MAXN = 200005 ;
struct Node {
int x , y ;
char op ;
} opp[MAXN] ;
int maxv[MAXN << 2] ;
int a[MAXN] , cnt ;
set < int > p[MAXN] ;
int n ;
void update ( int pos , int o , int l , int r ) {
if ( l == r ) {
if ( p[pos].empty () ) maxv[o] = 0 ;
else maxv[o] = *p[pos].rbegin () ;//返回end的值
return ;
}
int m = mid ;
if ( pos <= m ) update ( pos , lson ) ;
else update ( pos , rson ) ;
maxv[o] = max ( maxv[ls] , maxv[rs] ) ;
}
int query ( int L , int R , int key , int o , int l , int r ) {
if ( maxv[o] <= key ) return 0 ;
if ( l == r ) return l ;
int m = mid ;
if ( R <= m ) return query ( L , R , key , lson ) ;
if ( m < L ) return query ( L , R , key , rson ) ;
int res = query ( L , R , key , lson ) ;
if ( !res ) res = query ( L , R , key , rson ) ;
return res ;
}
int unique ( int n ) {
int cnt = 1 ;
sort ( a + 1 , a + n + 1 ) ;
FOR ( i , 2 , n ) if ( a[i] != a[cnt] ) a[++ cnt] = a[i] ;
return cnt ;
}
int hash ( int x ) {
int l = 1 , r = cnt , m ;
while ( l < r ) {
m = mid ;
if ( a[m] >= x ) r = m ;
else l = m + 1 ;
}
return l ;
}
void solve () {
char buf[10] ;
FOR ( i , 1 , n ) {
scanf ( "%s%d%d" , buf , &opp[i].x , &opp[i].y ) ;
a[i] = opp[i].x ;
opp[i].op = buf[0] ;
p[i].clear () ;
}
cnt = unique ( n ) ;
FOR ( i , 1 , n ) {
int x = hash ( opp[i].x ) , y = opp[i].y ;
if ( opp[i].op == 'a' ) {
p[x].insert ( y ) ;
update ( x , root ) ;
} else if ( opp[i].op == 'r' ) {
p[x].erase ( y ) ;
update ( x , root ) ;
} else {
if ( x + 1 > cnt ) x = 0 ;
if ( x ) x = query ( x + 1 , cnt , y , root ) ;
if ( x ) printf ( "%d %d\n" , a[x] , *p[x].upper_bound ( y ) ) ;
else printf ( "-1\n" ) ;
}
}
}
int main () {
while ( ~scanf ( "%d" , &n ) ) solve () ;
return 0 ;
}