題目:http://acm.hdu.edu.cn/showproblem.php?pid=3627
來源:2010 Asia Regional Tianjin Site —— Online Contest思路:將讀入的數據排序後離散化,以下標爲葉子節點建立線段樹,葉子節點存儲該位置處的列值,非葉子節點存儲該區間中葉子的最大列值。然後進行線段樹的插入、刪除和查找【給定查找區間】
!!!find_i函數位置的確定!!!查詢時的比較
// hdoj 3627 Giant For
// wa ce wa re ac 1609MS 12732K
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define FOR(i,a,b) for(i = (a); i < (b); ++i)
#define FORE(i,a,b) for(i = (a); i <= (b); ++i)
#define FORD(i,a,b) for(i = (a); i > (b); --i)
#define FORDE(i,a,b) for(i = (a); i >= (b); --i)
#define max(a,b) ((a) > (b)) ? (a) : (b)
#define min(a,b) ((a) < (b)) ? (a) : (b)
#define CLR(a,b) memset(a,b,sizeof(a))
#define PB(x) push_back(x)
const int MAXN = 200010;
const int MAXM = 0;
const int hash_size = 25000002;
const int INF = 0x7f7f7f7f;
int n, cnt, cas = 1;
char ch[MAXN][10];
struct node {
int l, r;
int max_cal;
}seg_tree[MAXN * 4];
struct data {
int x, y;
}num[MAXN], st[MAXN], endd[MAXN];
int find_i(int x, int y) {
int l = 1, r = cnt, mid;
while(l <= r) {
mid = (l + r) >> 1;
//!!!
if(endd[mid].x > x)
r = mid - 1;
else
l = mid + 1;
}
while(--l) {
if(endd[l].y == y)
return l;
}
}
void build(int l, int r, int num) {
seg_tree[num].l = l;
seg_tree[num].r = r;
seg_tree[num].max_cal = 0;
int mid = (l + r) >> 1;
if(r > l) {
build(l, mid, num << 1);
build(mid + 1, r, (num << 1) | 1);
}
}
void insert(int i, int num) {
if(seg_tree[num].l == seg_tree[num].r) {
seg_tree[num].max_cal = endd[i].y;
return ;
}
int mid = (seg_tree[num].l + seg_tree[num].r) >> 1;
if(i <= mid)
insert(i, num << 1);
else
insert(i, (num << 1) | 1);
seg_tree[num].max_cal = max(seg_tree[num << 1].max_cal, seg_tree[(num << 1) | 1].max_cal);
}
void dele(int i, int num) {
if(seg_tree[num].l == seg_tree[num].r) {
seg_tree[num].max_cal = 0;
return ;
}
int mid = (seg_tree[num].l + seg_tree[num].r) >> 1;
if(i <= mid)
dele(i, num << 1);
else
dele(i, (num << 1) | 1);
}
int query(int i, int num, int l, int r) {
if(seg_tree[num].max_cal <= endd[i].y)
return -1;
if(seg_tree[num].l == seg_tree[num].r) {
//!!!
if(endd[seg_tree[num].l].x > endd[i].x && seg_tree[num].max_cal > endd[i].y)
return seg_tree[num].l;
return -1;
}
int ans = -1, mid = (seg_tree[num].l + seg_tree[num].r) >> 1;
if(l <= mid)
ans = query(i, num << 1, l, r);
if(r > mid && ans == -1)
ans = query(i, (num << 1) | 1, l, r);
return ans;
}
bool cmp(data a, data b) {
if(a.x != b.x)
return a.x < b.x;
return a.y < b.y;
}
void solve() {
int i;
sort(st + 1, st + 1 + n, cmp);
endd[1].x = st[1].x, endd[1].y = st[1].y;
cnt = 1;
FORE(i, 2, n) {
if(st[i].x == st[i - 1].x && st[i].y == st[i - 1].y)
continue;
else
endd[++cnt] = st[i];
}
endd[++cnt].x = INF, endd[cnt].y = INF;
build(1, cnt + 1, 1);
if(cas > 1)
printf("\n");
printf("Case %d:\n", cas++);
FORE(i, 1, n) {
int t = find_i(num[i].x, num[i].y);
if(!strcmp(ch[i], "add"))
insert(t, 1);
if(!strcmp(ch[i], "remove"))
dele(t, 1);
if(!strcmp(ch[i], "find")) {
int tmp = query(t, 1, t, cnt);
if(tmp == -1)
printf("-1\n");
else
printf("%d %d\n", endd[tmp].x, endd[tmp].y);
}
}
}
void init() {
int i;
FORE(i, 1, n) {
scanf("%s %d %d", ch[i], &num[i].x, &num[i].y);
st[i].x = num[i].x, st[i].y = num[i].y;
}
}
int main() {
while(scanf("%d", &n) == 1, n) {
init();
solve();
}
return 0;
}