Codeforces 19D(线段树+离散化)
2015-08-14 19:24
267 查看
题意:题意很好理解,三种操作: (1)add x y,添加坐标(x,y),(2)del x y,删除坐标(x,y),(3)find x y,找到并输出严格大于(x,y)的坐标里的最小坐标。
题解:因为点有200000个,而点坐标最大到1e9,所以要离散化处理,我们只需要对x离散化,然后每个x对应一个set存y,然后每次修改操作的时候,根据set内的值维护最大y。
题解:因为点有200000个,而点坐标最大到1e9,所以要离散化处理,我们只需要对x离散化,然后每个x对应一个set存y,然后每次修改操作的时候,根据set内的值维护最大y。
#include <cstdio> #include <cstring> #include <set> #include <algorithm> using namespace std; const int N = 200100; struct Point { int x, y; Point(int a = -1, int b = -1): x(a), y(b) {} }P ; set<int> py ; struct Tree { int maxp; }tree[N << 2]; int n, num , res; char str [10]; void build(int k, int left, int right) { tree[k].maxp = -1; if (left != right) { int mid = (left + right) / 2; build(k * 2, left, mid); build(k * 2 + 1, mid + 1, right); } } void pushup(int k) { tree[k].maxp = max(tree[k * 2].maxp, tree[k * 2 + 1].maxp); } void modify(int k, int left, int right, int pos) { if (left == right) { if (py[pos].size()) tree[k].maxp = *(--py[pos].end()); else tree[k].maxp = -1; return; } int mid = (left + right) / 2; if (pos <= mid) modify(k * 2, left, mid, pos); else modify(k * 2 + 1, mid + 1, right, pos); pushup(k); } void query(int k, int left, int right, int pos, int p) { if (right <= pos) return; if (tree[k].maxp <= p) return; if (left == right) { res = left; return; } int mid = (left + right) / 2; query(k * 2, left, mid, pos, p); if (res == -1) query(k * 2 + 1, mid + 1, right, pos, p); } int main() { scanf("%d", &n); int cnt = 0; for (int i = 1; i <= n; i++) { scanf("%s%d%d", str[i], &P[i].x, &P[i].y); if (str[i][0] == 'a') num[++cnt] = P[i].x; } sort(num + 1, num + 1 + cnt); cnt = unique(num + 1, num + 1 + cnt) - (num + 1); for (int i = 1; i <= cnt; i++) py[i].clear(); if (cnt == 0) tree[1].maxp = -1; else build(1, 1, cnt); for (int i = 1; i <= n; i++) { int pos = upper_bound(num + 1, num + 1 + cnt, P[i].x) - (num + 1); if (str[i][0] == 'a') { py[pos].insert(P[i].y); modify(1, 1, cnt, pos); } else if (str[i][0] == 'r') { py[pos].erase(P[i].y); modify(1, 1, cnt, pos); } else { res = -1; if (pos <= cnt) query(1, 1, cnt, pos, P[i].y); if (res == -1) printf("-1\n"); else printf("%d %d\n", num[res], *py[res].upper_bound(P[i].y)); } } return 0; }
相关文章推荐
- Apache与Tomcat 区别联系
- C# 、Vb .Net 中 Datagridview显示行号方法。
- 【求无向图的桥,有重边】ZOJ - 2588 Burning Bridges
- Triangle LOVE
- 解读核心动画类
- (转)Apache与Tomcat 区别联系
- dede整站迁移
- OC - NSArrayAndNSMutableArray
- C++ 运算符重载(二)
- HDU 4857 逃生 【逆拓扑 优先队列】
- 字符串的排序(多种方法)
- Qt打包生成exe程序
- HTTP通信中的请求转发和请求重定向
- vector::clear
- hold 命令
- 登录注册代码
- hold 命令
- 最大子段和
- Caocao's Bridges---hdu4738(桥)
- hdu 1325 Is It A Tree?(并查集)