Codeforces-19D Point---线段树

题目链接:

https://cn.vjudge.net/problem/CodeForces-19D

题目大意:

n个操作,在200000*200000的平面上加删点

find 严格在坐标右上角,x最小,再y最小的点

解题思路:

线段树,离散化x坐标,线段树中保存y最大值,这样可以找到严格大于点x' y'的最小的x,用set存储每个x的y,就可以找到大于y'的y

 

 1 #include<bits/stdc++.h>
 2 #define mid(l, r) ((l) + ((r) - (l)) / 2)
 3 #define lc ((o)<<1)
 4 #define rc ((o)<<1|1)
 5 using namespace std;
 6 const int maxn = 1e6 + 10;
 7 typedef long long ll;
 8 struct Edge
 9 {
10     int op, x, y;
11     Edge(){}
12     Edge(int op, int x, int y):op(op), x(x), y(y){}
13 }a[maxn];//存储离线操作
14 int num[maxn];//去重
15 struct node
16 {
17     int l, r, y;//每个x存储最大的y
18 }tree[maxn];//线段树
19 set<int>tot[maxn];//存储x中的y
20 
21 void build(int o, int l, int r)
22 {
23     tree[o].l = l, tree[o].r = r, tree[o].y = -1;
24     if(l == r)return;
25     int m = mid(l, r);
26     build(lc, l, m);
27     build(rc, m + 1, r);
28 }
29 int p;
30 void update(int o)
31 {
32     if(tree[o].l == tree[o].r)
33     {
34         if(tot[p].size())tree[o].y = *(--tot[p].end());
35         else tree[o].y = -1;
36         return;
37     }
38     if(p <= tree[lc].r)update(lc);
39     else update(rc);
40     tree[o].y = max(tree[lc].y, tree[rc].y);
41 }
42 int query(int x, int y, int o)
43 {
44     if(tree[o].r <= x)return -1;
45     if(tree[o].y <= y)return -1;
46     if(tree[o].l == tree[o].r)return tree[o].l;
47     int t = query(x, y, lc);
48     if(t == -1)t = query(x, y, rc);
49     return t;
50 }
51 int main()
52 {
53     int n;char s[10];
54     cin >> n;
55     for(int i = 1; i <= n; i++)
56     {
57         scanf("%s%d%d", s, &a[i].x, &a[i].y);
58         if(s[0] == 'a')a[i].op = 1;
59         else if(s[0] == 'r')a[i].op = 2;
60         else a[i].op = 3;
61         num[i] = a[i].x;
62     }
63     sort(num + 1, num + 1 + n);
64     int m = unique(num + 1, num + 1 + n) - (num + 1);
65     build(1, 1, m);
66     for(int i = 1; i <= n; i++)
67     {
68         int x = upper_bound(num + 1, num + 1 + m, a[i].x) - (num + 1);
69         int y = a[i].y;
70         p = x;
71         if(a[i].op == 1)
72         {
73             tot[x].insert(y);
74             update(1);
75         }
76         else if(a[i].op == 2)
77         {
78             tot[x].erase(y);
79             update(1);
80         }
81         else
82         {
83             int ans = query(x, y, 1);
84             if(ans == -1)puts("-1");
85             else printf("%d %d\n", num[ans], *tot[ans].upper_bound(y));
86         }
87     }
88     return 0;
89 }

 

posted @ 2018-06-01 15:07  _努力努力再努力x  阅读(382)  评论(0编辑  收藏  举报