hdu 4268 Alice and Bob 区域赛 1002 (STL、SBT实现)

题目:
     给出2*n个矩形(给出长和宽),问前n个矩形能够套上最多多少个后n个矩形

分析:
     把前n个矩形与后n个矩形分开在两数组中,然后分别先对长x(或宽)排序,排序结束后,只需要满足另外一个条件y就行。
     在这里我们利用贪心的思想,每次从后n个矩形中满足x1>=x2且y2值尽可能最大,要维护y2值最大,我们可以使用平衡树(SBT、AVL、TREAP)或者Splay来维护都行,另外可利用STL的福利,直接调用multiset<int> s;维护即可,具体的应用请百度、谷歌,代码如下:

    稍后我把SBT的弄上来

View Code
SBT的如下:
View Code
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 
  6 using namespace std;
  7 
  8 const int X = 100010;
  9 const int inf = 2e9;
 10 
 11 int n,root,tol;
 12 
 13 struct qq{
 14     int x,y;
 15     friend bool operator < (qq a,qq b){
 16         return a.x<b.x||(a.x==b.x&&a.y<b.y);
 17     }
 18 }a[X],b[X];
 19 
 20 struct node{
 21     int val,l,r,s;
 22     void init(int _val){
 23         l = r = 0;
 24         s = 1;
 25         val = _val;
 26     }
 27 }sbt[X];
 28 
 29 void left_rotate(int &t){
 30     int k = sbt[t].r;
 31     sbt[t].r = sbt[k].l;
 32     sbt[k].l = t;
 33     sbt[k].s = sbt[t].s;
 34     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 35     t = k;
 36 }
 37 
 38 void right_rotate(int &t){
 39     int k = sbt[t].l;
 40     sbt[t].l = sbt[k].r;
 41     sbt[k].r = t;
 42     sbt[k].s = sbt[t].s;
 43     sbt[t].s = sbt[sbt[t].l].s+sbt[sbt[t].r].s+1;
 44     t = k;
 45 }
 46 
 47 void maintain(int &t,bool ok){
 48     if(!ok){
 49         if(sbt[sbt[sbt[t].l].l].s>sbt[sbt[t].r].s)
 50             right_rotate(t);
 51         else if(sbt[sbt[sbt[t].l].r].s>sbt[sbt[t].r].s){
 52             left_rotate(sbt[t].l);
 53             right_rotate(t);
 54         }
 55         else return;
 56     }
 57     else{
 58         if(sbt[sbt[sbt[t].r].r].s>sbt[sbt[t].l].s)
 59             left_rotate(t);
 60         else if(sbt[sbt[sbt[t].r].l].s>sbt[sbt[t].l].s){
 61             right_rotate(sbt[t].r);
 62             left_rotate(t);
 63         }
 64         else return;
 65     }
 66     maintain(sbt[t].l,0);
 67     maintain(sbt[t].r,1);
 68     maintain(t,0);
 69     maintain(t,1);
 70 }
 71 
 72 void insert(int &t,int val){
 73     if(!t){
 74         t = ++tol;
 75         sbt[t].init(val);
 76         return;
 77     }
 78     sbt[t].s++;
 79     if(val<sbt[t].val)
 80         insert(sbt[t].l,val);
 81     else
 82         insert(sbt[t].r,val);
 83     maintain(t,val>=sbt[t].val);
 84 }
 85 
 86 int del(int &t,int val){
 87     if(!t)
 88         return 0;
 89     sbt[t].s--;
 90     if(sbt[t].val==val||(val<sbt[t].val&&!sbt[t].l)||(val>sbt[t].val&&!sbt[t].r)){
 91         if(sbt[t].l&&sbt[t].r){
 92             int pos = del(sbt[t].l,val+1);
 93             sbt[t].val = sbt[pos].val;
 94             return pos;
 95         }
 96         else{
 97             int pos = t;
 98             t = sbt[t].l+sbt[t].r;
 99             return pos;
100         }
101     }
102     else
103         return del(val<sbt[t].val?sbt[t].l:sbt[t].r,val);
104 }
105 
106 int get_pre(int t,int val){
107     if(!t)
108         return inf;
109     if(val<sbt[t].val)
110         return get_pre(sbt[t].l,val);
111     else if(val==sbt[t].val)
112         return val;
113     else{
114         int temp = get_pre(sbt[t].r,val);
115         return temp==inf?sbt[t].val:temp;
116     }
117 }
118 
119 int main(){
120     freopen("sum.in","r",stdin);
121     int ncase;
122     cin>>ncase;
123     while(ncase--){
124         cin>>n;
125         for(int i=0;i<n;i++)
126             scanf("%d%d",&a[i].x,&a[i].y);
127         for(int i=0;i<n;i++)
128             scanf("%d%d",&b[i].x,&b[i].y);
129         sort(a,a+n);
130         sort(b,b+n);
131         int j = 0;
132         int ans = 0;
133         root = tol = 0;
134         for(int i=0;i<n;i++){
135             while(j<n&&b[j].x<=a[i].x){
136                 insert(root,b[j].y);
137                 j++;
138             }
139             if(sbt[root].s==0)
140                 continue;
141             int temp = get_pre(root,a[i].y);
142             if(temp<=a[i].y){
143                 ans++;
144                 del(root,temp);
145             }
146         }
147         cout<<ans<<endl;
148     }
149     return 0;
150 }
 1 #include <set>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 
 7 using namespace std;
 8 
 9 const int maxn = 1e6+5;
10 
11 struct node{
12     int x,y;
13     friend bool operator < (node a,node b){
14         return a.x<b.x||(a.x==b.x&&a.y<b.y);
15     }
16 }a[maxn],b[maxn];
17 
18 multiset<int> s;
19 int n;
20 
21 int main(){
22     freopen("sum.in","r",stdin);
23     int ncase;
24     cin>>ncase;
25     while(ncase--){
26         cin>>n;
27         for(int i=0;i<n;i++)
28             scanf("%d%d",&a[i].x,&a[i].y);
29         for(int i=0;i<n;i++)
30             scanf("%d%d",&b[i].x,&b[i].y);
31         sort(a,a+n);
32         sort(b,b+n);
33         set<int>::iterator it;
34         s.clear();
35         int j = 0;
36         int ans = 0;
37         for(int i=0;i<n;i++){
38             while(j<n&&b[j].x<=a[i].x){
39                 s.insert(b[j].y);
40                 j++;
41             }
42             if(s.size()==0)
43                 continue;
44             it = s.upper_bound(a[i].y);
45             if(it!=s.begin()){
46                 ans++;
47                 it--;
48                 s.erase(it);
49             }
50         }
51         cout<<ans<<endl;
52     }
53     return 0;
54 }
原文地址:https://www.cnblogs.com/yejinru/p/2677104.html