1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| struct Disc { } disc;
set<int> st[maxn];
#define ls ( u << 1 ) #define rs ( u << 1 | 1 )
struct SegTree {
struct Node { int l, r; int mx; } tr[maxn << 2];
void push_up( int u ) { tr[u].mx = max( tr[ls].mx, tr[rs].mx ); }
void build( int u, int l, int r ) { tr[u] = { l, r, 0 }; if( l == r ) return ; int mid = ( l + r ) >> 1; build( ls, l, mid ); build( rs, mid + 1, r ); }
void upd( int u, int pos, int val ) { if( tr[u].l == tr[u].r ) { tr[u].mx = val; return ; } int mid = ( tr[u].l + tr[u].r ) >> 1; if( pos <= mid ) upd( ls, pos, val ); else upd( rs, pos, val ); push_up( u ); }
int find_first( int u, int l, int r, ll val ) { if( r < tr[u].l || tr[u].r < l || tr[u].mx < val ) return 0; if( tr[u].l == tr[u].r ) return tr[u].l; int pos = find_first( ls, l, r, val ); if( pos ) return pos; return find_first( rs, l, r, val ); }
} seg;
struct Query { int opt, x, y; } qs[maxn];
void solve( ) { int n = read( ); for( int i = 1; i <= n; ++ i ) { string opt; cin >> opt; int x = read( ), y = read( ); if( opt == "add" ) qs[i] = { 1, x, y }; else if( opt == "remove") qs[i] = { 2, x, y }; else qs[i] = { 3, x, y }; disc.add( x ), disc.add( y ); }
disc.init( ); int m = disc.size( ); seg.build( 1, 1, m );
for( int i = 1; i <= n; ++ i ) { qs[i].x = disc.get_idx( qs[i].x ); qs[i].y = disc.get_idx( qs[i].y ); }
for( int i = 1; i <= n; ++ i ) { auto [opt, x, y] = qs[i]; if( opt == 1 ) { st[x].insert( y ); seg.upd( 1, x, *st[x].rbegin( ) ); } else if( opt == 2 ) { auto it = st[x].find( y ); st[x].erase( it ); if( st[x].empty( ) ) seg.upd( 1, x, 0 ); else seg.upd( 1, x, *st[x].rbegin( ) ); } else { int pos = seg.find_first( 1, x + 1, m, y + 1 ); if( pos == 0 ) { cout << "-1" << '\n'; continue; } auto it = st[pos].upper_bound( y ); cout << disc.get_val( pos ) << " "; cout << disc.get_val( *it ) << '\n'; } } }
|