CF 19D, 线段树套set/KD-tree
题目大意:有n个操作,要么在平面上增删一个点,要么询问某个坐标右上侧(严格大于等于)第一个点是谁(x相同取y最小)。
解:非常智障看错题了,没看到要在右上,所以写了个树套set,发现看错题嘀咕了一下艹这询问set搞不来,想了一下似乎kd-tree可以做,就写了棵,常数卡得很死过了。后来看题解还真是树套set。离散化后每个线段都是一个set,然后插入删除的时候沿途把set搞一下,询问的时候用个小技巧就行了,还是很简单的。
1 #include <cstdio> 2 #include <string> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 #include <cstring> 7 #include <complex> 8 #include <set> 9 #include <vector> 10 #include <map> 11 #include <queue> 12 #include <deque> 13 #include <ctime> 14 15 using namespace std; 16 17 const double EPS = 1e-8; 18 19 #define ABS(x) ((x)<0?(-(x)):(x)) 20 #define SQR(x) ((x)*(x)) 21 #define MIN(a,b) ((a)<(b)?(a):(b)) 22 #define MAX(a,b) ((a)>(b)?(a):(b)) 23 24 #define LSON(x) ((x)<<1) 25 #define RSON(x) (((x)<<1)+1) 26 #define LOWBIT(x) ((x)&(-(x))) 27 #define MAXS 1111 28 #define MAXN 222222 29 #define VOIDPOINT 0 30 #define LL long long 31 #define OO 214748364 32 #define INF 0x3f3f3f3f 33 #define MP(x,y) make_pair(x,y) 34 35 int index; 36 37 struct node{ 38 int xy[2]; 39 node(int a = 0, int b = 0) { 40 xy[0] = a; xy[1] = b; 41 } 42 bool operator < (const node &rhs) const { 43 if (xy[index] == rhs.xy[index]) return xy[index^1] < rhs.xy[index^1]; 44 return xy[index] < rhs.xy[index]; 45 } 46 }; 47 48 char str[111]; 49 50 struct ask{ 51 int type, x, y; 52 void read() { 53 scanf("%s %d %d", str, &x, &y); 54 type = str[0] == 'a' ? 0 : (str[0] == 'r' ? 1 : 2); 55 } 56 } q[MAXN]; 57 58 vector<pair<int, int > >lsh; 59 node b[MAXN]; 60 61 struct KDTREE{ 62 int lson[MAXN*4], rson[MAXN*4], size[MAXN*4], alive[MAXN*4]; 63 int minx[MAXN*4], maxx[MAXN*4], miny[MAXN*4], maxy[MAXN*4]; 64 node a[MAXN*4]; 65 int gx, gy, gz; 66 void setting(int a = 0, int b = 0, int c = 0) { 67 gx = a; gy = b; gz = c; 68 } 69 void build(int kok, int l, int r, int dep) { 70 if (l > r) return ; 71 72 alive[kok] = size[kok] = 0; 73 int mid = (l + r) >> 1; 74 index = dep & 1; 75 76 nth_element(b + l, b + mid, b + r + 1); 77 a[kok] = b[mid]; 78 // cout << kok << ' ' << a[kok].xy[0] <<' '<< a[kok].xy[1] << endl; 79 80 build(LSON(kok), l, mid-1, dep+1); 81 build(RSON(kok), mid+1, r, dep+1); 82 } 83 void insert(int kok = 1, int dep = 0) { 84 ////cout << kok << ' '<< a[kok].xy[0] <<' '<< a[kok].xy[1] << endl; 85 while (1) { 86 size[kok] += gz; 87 if (gx == a[kok].xy[0] && gy == a[kok].xy[1]) { 88 alive[kok] += gz; 89 return ; 90 } 91 index = dep & 1; 92 ++dep; 93 if (node(gx, gy) < a[kok]) kok = LSON(kok);//insert(LSON(kok), dep + 1); 94 else kok = RSON(kok); //insert(RSON(kok), dep + 1); 95 } 96 //size[kok] = size[LSON(kok)] + alive[kok] + size[RSON(kok)]; 97 } 98 pair<int, int > query(int kok = 1, int dep = 0) { 99 if (size[kok] == 0) return MP(INF, INF); 100 index = dep & 1; 101 // cout << kok << ' '<< a[kok].xy[0] <<' '<< a[kok].xy[1] << endl; 102 pair<int ,int > ans = MP(INF, INF); 103 if (index == 1) { //node(gx, gy) < a[kok] || gy == a[kok].xy[1] ? : MP(INF, INF) 104 if (size[RSON(kok)]) ans = query(RSON(kok), dep+1); 105 if (gy <= a[kok].xy[1] && size[LSON(kok)]) ans = min(ans, query(LSON(kok), dep+1)); 106 if (alive[kok] && gx < a[kok].xy[0] && gy < a[kok].xy[1]) ans = min(ans, MP(a[kok].xy[0], a[kok].xy[1])); 107 return ans; 108 } 109 if (gx < a[kok].xy[0]) { 110 if (alive[kok] && gy < a[kok].xy[1]) ans = MP(a[kok].xy[0], a[kok].xy[1]); 111 if (size[LSON(kok)]) ans = min(ans, query(LSON(kok), dep+1)); 112 } 113 if (ans.first == INF) { 114 if (size[RSON(kok)]) ans = query(RSON(kok), dep + 1); 115 } 116 //!! 117 return ans; 118 } 119 } Tree; 120 121 int n; 122 123 void init() { 124 scanf("%d", &n); 125 for (int i = 0; i < n; ++i) { 126 q[i].read(); 127 lsh.push_back(MP(q[i].x, q[i].y)); 128 } 129 sort(lsh.begin(), lsh.end()); 130 lsh.erase(unique(lsh.begin(), lsh.end()), lsh.end()); 131 for (int i = 0; i < lsh.size(); ++i) b[i] = node(lsh[i].first, lsh[i].second); 132 Tree.build(1, 0, lsh.size()-1, 0); 133 } 134 135 void solve() { 136 for (int tt = 0; tt < n; ++tt) { 137 if (q[tt].type == 0) { 138 //cout << q[tt].x << ' ' << q[tt].y << endl; 139 Tree.setting(q[tt].x, q[tt].y, 1); 140 Tree.insert(); 141 } else if (q[tt].type == 1) { 142 Tree.setting(q[tt].x, q[tt].y, -1); 143 Tree.insert(); 144 } else { 145 Tree.setting(q[tt].x, q[tt].y); 146 pair<int, int > ans = Tree.query(); 147 if (ans.first == INF) puts("-1"); 148 else printf("%d %d\n", ans.first, ans.second); 149 } 150 } 151 } 152 153 int main() { 154 // freopen("test.txt", "r", stdin); 155 init(); 156 solve(); 157 return 0; 158 }