UVA_11020 Efficient Solutions 【平衡二叉搜索树set用法】

一、题面

UVA11020

二、分析

最近脑子有点不好使吧,这题还想了很久。

对于给定的两个值要满足题面中的条件,那么我们可以把这两个值转化到平面中的坐标去理解。

首先,需要考虑的是维护的所有点其实是一个严格有序的,画个图就可以理解了。

此时,在维护的所有点的基础上,如果来了一个点,我们可以先考虑x坐标。

如果这个点x值比所有维护的点中最小的x值还小,那么它必然是有效的,之间加入,再删除后面被这个点控制的点。

如果这个点的y值比在象限中它前面(相对于x)的点的y值要大,那就不需要加入了,因为被它前面这个点控制了。

如果比它前面这个点的y值小,其实就需要加入,因为本身维护的所有点是有序的,那么这个点加入之后必然是有效的,接下来就可以考虑删除被这个点控制的点了。

删除点的话,只需要考虑后面x值比当前点大的点,且y值比当前点大。画个图就好理解了。

实现的话,用有序的且可以重复的multiset,结合lower_bound和upper_bound。

三、AC代码

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 struct Node
 6 {
 7     int l, c;
 8     bool operator<(const Node &t)const
 9     {
10         return l < t.l || (l ==  t.l && c < t.c);
11     }
12 };
13 
14 int main()
15 {
16     //freopen("input.txt", "r", stdin);
17     int T, N;
18     scanf("%d", &T);
19     for(int Case = 1; Case <= T; Case++)
20     {
21         if(Case > 1)    puts("");
22         printf("Case #%d:\n", Case);
23         multiset<Node> ST;
24         Node p;
25         scanf("%d", &N);
26         for(int i = 0; i < N; i++)
27         {
28             scanf("%d %d", &p.l, &p.c);
29             multiset<Node>::iterator itr = ST.lower_bound(p);
30             if(itr == ST.begin() || (--itr)->c > p.c)
31             {
32                 ST.insert(p);
33                 itr = ST.upper_bound(p);
34                 while(itr != ST.end() && itr->c >= p.c) ST.erase(itr++);
35             }
36             printf("%d\n", ST.size());
37         }
38     }
39     return 0;
40 }

 

posted @ 2019-04-08 22:35  Dybala21  阅读(150)  评论(0编辑  收藏  举报