1. 程式人生 > >bzoj1730 [Usaco2005 dec]Barn Expansion 牛棚擴張

bzoj1730 [Usaco2005 dec]Barn Expansion 牛棚擴張

extra there 它的 存在 please discus single usaco 輸入

1730: [Usaco2005 dec]Barn Expansion 牛棚擴張

Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 134 Solved: 72
[Submit][Status][Discuss]

Description

Farmer John has N (1 <= N <= 25,000) rectangular barns on his farm, all with sides parallel to the X and Y axes and integer corner coordinates in the range 0..1,000,000. These barns do not overlap although they may share corners and/or sides with other barns. Since he has extra cows to milk this year, FJ would like to expand some of his barns. A barn has room to expand if it does not share a corner or a wall with any other barn. That is, FJ can expand a barn if all four of its walls can be pushed outward by at least some amount without bumping into another barn. If two barns meet at a corner, neither barn can expand. Please determine how many barns have room to expand.

約翰有N(1≤N≤25000)個矩形牛棚,它們的墻均與坐標軸平行,而且其坐標在[o,1061範圍內.任意兩個牛棚不重疊,但可能會有公共的墻. 由於約翰的奶牛持續增加,他不得不考慮擴張牛棚.一個牛棚可以擴張,當且僅當它的四邊均不與其它牛棚接觸.如果兩個牛棚有一個公共角,那它們均是不可擴張的.統計有多少牛棚可以擴張.

Input

* Line 1: A single integer, N

* Lines 2..N+1: Four space-separated integers A, B, C, and D, describing one barn. The lower-left corner of the barn is at (A,B) and the upper right corner is at (C,D).

第1行輸入N,之後N行每行輸入一個牛棚的左下角和右上角坐標. 輸出說明

Output

* Line 1: A single integer that is the number of barns that can be expanded.

輸出可擴張的牛棚數.

Sample Input

5
0 2 2 7
3 5 5 8
4 2 6 4
6 1 8 6
0 0 8 1

INPUT DETAILS:

There are 5 barns. The first barn has its lower-left corner at (0,2) and
its upper-right corner at (2,7), and so on.

Sample Output

2

僅有前兩個牛棚可以擴張.

HINT

Source

Gold

[Submit][Status][Discuss]

大力掃描線 防止一些麻煩的情況就從左往右和從右往左都做一遍

把一個矩形拆成兩個部分 (l,d,u) (r,d,u) 表示橫坐標為l/r 縱坐標從d到u的兩個線段

然後按照橫坐標排序 如果橫坐標相等則插入的優先

然後先處理新插入的情況 這題矩形有交只有兩種情況 上下相鄰和左右相鄰

上下相鄰比較好處理

  開兩個個O(M)的數組 M是坐標大小

  f[i][0]表示以i為下端點的矩形的號碼

  f[i][1]表示以i為上端點的矩形的號碼

  因為矩形不存在重疊等情況 所以在任何時刻他的值是唯一的

  所以可以插入的時候查詢一下那兩個端點就可以了

左右情況可以開兩個O(M)樹狀數組

  第一個F1(x) 記錄下端點為x的前綴和

  第二個F2(x) 記錄上端點為x的前綴和

  如果一個矩形和其他的有左右相鄰的話

  那麽如果 F1(u)-F2(d) > 0就表示有相鄰(稍微YY一下比較顯然)

這樣開一個bool數組記錄一下是否已經不行了 最後答案就是bool數組裏為0的個數

代碼:

  1 #include<set>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 #define Rep(i,x,y) for(int i=x;i<y;++i)
  7 #define For(i,x,y) for(int i=x;i<=y;++i)
  8 using namespace std;
  9 const int N = 3e5+5;
 10 const int M = 1e6+5;
 11 struct data{
 12     int x,u,d,id;
 13     bool kd;
 14     bool operator < (const data&b) const{
 15         return x<b.x||x==b.x&&kd<b.kd;
 16     }
 17 }a[N];
 18 struct bit{
 19     int c[M];
 20     #define lowbit(x) (x&-x)
 21     void insert(int x){
 22         for(int i=x;i<M;i+=lowbit(i))
 23             c[i]++;
 24     }
 25     void erase(int x){
 26         for(int i=x;i<M;i+=lowbit(i))
 27             c[i]--;    
 28     }
 29     int query(int x){
 30         if(!x) return 0;
 31         int res=0;
 32         for(int i=x;i;i-=lowbit(i))
 33             res+=c[i];
 34         return res;
 35     }
 36     void init(){
 37         memset(c,0,sizeof(c));
 38     }
 39 }T1,T2;
 40 int cnt;
 41 int n;
 42 bool nok[N];
 43 int f[M][2];
 44 void del(int i){
 45     T1.erase(a[i].d);
 46     T2.erase(a[i].u+1);
 47     f[a[i].u][0]=0;
 48     f[a[i].d][1]=0;
 49 }
 50 void INS(int i){
 51     f[a[i].u][0]=a[i].id;
 52     f[a[i].d][1]=a[i].id;
 53     T1.insert(a[i].d);
 54     T2.insert(a[i].u+1);
 55 }
 56 void ins(int l,int r){
 57     For(i,l,r)
 58         INS(i);
 59     For(i,l,r){
 60         del(i);
 61         if(f[a[i].u][1]){
 62             nok[a[i].id]=1;
 63             nok[f[a[i].u][1]]=1;
 64         }
 65         if(f[a[i].d][0]){
 66             nok[a[i].id]=1;
 67             nok[f[a[i].d][0]]=1;
 68         }
 69         if(T1.query(a[i].u)-T2.query(a[i].d)>0) nok[a[i].id]=1;
 70         INS(i);
 71     }
 72 }
 73 int main(){
 74     scanf("%d",&n);
 75     For(i,1,n){
 76         int l,r,u,d;
 77         scanf("%d%d%d%d",&l,&d,&r,&u);
 78         ++l;++r;++d;++u;
 79         a[++cnt]=(data){l,u,d,i,0};
 80         a[++cnt]=(data){r,u,d,i,1};
 81     }
 82     n<<=1;
 83     sort(a+1,a+n+1);
 84     for(int i=1;i<=n;){
 85         int l=i;int r=i;
 86         for(;r<=n&&a[r].x==a[l].x&&a[r].kd==0;++r);
 87         ins(l,r-1);
 88         for(;r<=n&&a[r].kd==1;++r) 
 89             del(r);
 90         i=r;
 91     }
 92     memset(f,0,sizeof(f));
 93     T1.init();
 94     T2.init();
 95     for(int i=n;i;){
 96         int r=i;int l=i;
 97         for(;l>0&&a[l].x==a[r].x&&a[l].kd==1;--l);
 98         ins(l+1,r);
 99         for(;l>0&&a[l].kd==0;--l) del(l);
100         i=l;
101     }
102     int res=0;
103     For(i,1,n/2) if(!nok[i]) ++res;
104     cout<<res<<endl;
105     return 0;
106 }

bzoj1730 [Usaco2005 dec]Barn Expansion 牛棚擴張