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 }

你可能感兴趣的:(HDU)