标签:algorithm 离散化 区域 iter style main show one date
题意:在一个二维平面上 有三种操作
1.添加一个点
2.删去一个点
3.询问严格在(x, y)右上的点 先取最左 然后最低的
题解:先把x离散化 然后用线段树维护横坐标为x的最大值 同样把每个x开一个set 就可以处理添加和删除操作了
询问(x, y) 就是在横坐标大于x的区域 求第一个最大值大于y的x 然后我们就可以在x这个set里找第一个大于y的点了
注意好好写询问 单次是$log$的
#include <stdio.h> #include <algorithm> #include <iostream> #include <set> using namespace std; const int MAXN = 2e5 + 5; const int INF = 0x3f3f3f3f; int T, cnt; char s[25]; int opt[MAXN], x[MAXN], y[MAXN]; int b[MAXN]; set<int> st[MAXN]; int zd[MAXN << 2]; void pushup(int rt) { zd[rt] = max(zd[rt << 1], zd[rt << 1 | 1]); } void update(int k, int v, int l, int r, int rt) { if(l == r) { zd[rt] = max(zd[rt], v); return; } int mid = (l + r) >> 1; if(k <= mid) update(k, v, l, mid, rt << 1); else update(k, v, mid + 1, r, rt << 1 | 1); pushup(rt); } void change(int k, int v, int l, int r, int rt) { if(l == r) { zd[rt] = v; return; } int mid = (l + r) >> 1; if(k <= mid) change(k, v, l, mid, rt << 1); else change(k, v, mid + 1, r, rt << 1 | 1); pushup(rt); } int find(int pos, int v, int l, int r, int rt) { if(pos > cnt) return 0; if(zd[rt] <= v) return 0; if(l == r) return l; int mid = (l + r) >> 1; if(pos > mid) return find(pos, v, mid + 1, r, rt << 1 | 1); else { int res = 0; res = find(pos, v, l, mid, rt << 1); if(res < pos) res = find(pos, v, mid + 1, r, rt << 1 | 1); return res; } } int main() { scanf("%d", &T); for(int i = 1; i <= T; i++) { scanf("%s", s + 1); if(s[1] == ‘a‘) opt[i] = 1; else if(s[1] == ‘r‘) opt[i] = 2; else opt[i] = 3; scanf("%d%d", &x[i], &y[i]); b[++cnt] = x[i]; } sort(b + 1, b + 1 + cnt); cnt = unique(b + 1, b + 1 + cnt) - (b + 1); for(int i = 1; i <= T; i++) { int t = lower_bound(b + 1, b + 1 + cnt, x[i]) - b; if(opt[i] == 1) { st[t].insert(y[i]); update(t, y[i], 1, cnt, 1); } else if(opt[i] == 2) { set<int>::iterator it; it = st[t].lower_bound(y[i]); st[t].erase(*it); if(!st[t].size()) change(t, 0, 1, cnt, 1); else change(t, *st[t].end(), 1, cnt, 1); } else { int res = find(t + 1, y[i], 1, cnt, 1); if(res == 0) puts("-1"); else { set<int>::iterator it; it = st[res].upper_bound(y[i]); printf("%d %d\n", b[res], *it); } } } return 0; }
Codeforces 19D - Points (线段树 + set)
标签:algorithm 离散化 区域 iter style main show one date
原文地址:https://www.cnblogs.com/lwqq3/p/12804807.html