• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            算法學社
            記錄難忘的征途
            posts - 141,comments - 220,trackbacks - 0

            題意描述:

                10^7 * 10^7 的平面上有N(N<50,000)個不相交的矩形。要在這個平面上放置一個長度為M(M<1,000)的線段,有多少種方法。

            吐槽:

                1. 今天杭電被黑了.... 導致題解現在才出來....
                2. 果然還是自己寫對拍好,想要AC總是要付出代價的么.....

            算法分析:

                掃描線豎直的掃一遍,維護掃過的橫向區間集合... 每個空白的一段是我們想要的可以放線段的地方...
                
                由于插入一個線段只會刪除一個空白區間,增加兩個空白區間。這樣的話我們可以根據上一個事件點的情況,推出這個事件點的情況。
                刪除一個區間同理。
                那么如何知道增加和刪除的空白區間的長度呢?
                線段樹維護的是實際區間的最左點和最右點。
                插入一個區間[l,r]的時候,我們同時計算出[0,l)的最右點R和(r,inf)的最左點L。
                那么新的情況就是 new = last - f(R,L) + f(R,l) + f(r,L)
                刪除同理, 和求矩形周長并很像....
                
                我們加入兩個左右哨兵以防止空集的情況...
                trick:
                    1. n=0;
                    2. m=1;
                這兩個要額外討論一下,另外離散化的時候注意一下上邊和下邊。
                最后還要吐槽一句: 對拍是debug最有效的手段
              
              1 #include<iostream>
              2 #include<cstring>
              3 #include<algorithm>
              4 #include<cstdio>
              5 #include<cassert>
              6 using namespace std;
              7 typedef long long ll;
              8 template <typename T> inline void chkmax(T &a,const T b){ if(a < b) a=b;}
              9 template <typename T> inline void chkmin(T &a,const T b){ if(a > b) a=b;}
             10 const int N = 100005;
             11 int lt[N<<2],rt[N<<2],cnt[N<<2];
             12 int w,h,n,m,L,R;
             13 int X[N],num[N][4];
             14 struct node{
             15     int l,r,h,p;
             16     node(){}
             17     node(int L,int R,int H,int P):l(L),r(R),h(H),p(P){}
             18     bool operator < (const node &A) const {
             19         return h == A.h? p < A.p: h < A.h;
             20     }
             21 } seg[N];
             22 // segment_tree
             23 inline void upt(int pos,int l,int r){
             24     assert(!cnt[pos] && l<r);
             25     lt[pos] = lt[pos<<1] == -1 ? lt[pos<<1|1] : lt[pos<<1];
             26     rt[pos] = rt[pos<<1|1] == -1 ? rt[pos<<1] : rt[pos<<1|1];
             27 }
             28 void update(int l,int r,int pos,int ML,int MR,int ct){
             29     if(r >= MR && l <= ML){
             30         cnt[pos] += ct;
             31         if(cnt[pos]) lt[pos] = ML==l? l:-1, rt[pos] = MR == r ? r:-1;
             32         else lt[pos] = rt[pos] = -1;
             33         return;
             34     }
             35     int mid = ML + MR >>1;
             36     if(mid >= l) update(l,r,pos<<1,ML,mid,ct);
             37     else chkmax(R,rt[pos<<1]);
             38     if(mid < r) update(l,r,pos<<1|1,mid+1,MR,ct);
             39     else if(lt[pos<<1|1]!=-1) chkmin(L,lt[pos<<1|1]);
             40     upt(pos,ML,MR);
             41 }
             42 // sweep line
             43 ll cal(int len,int m){
             44     if(m>len) return 0;
             45     return len -m + 1;
             46 }
             47 int search(int val,int n){
             48     int l =0, r = n;
             49     while(l<r){
             50         int mid = l + r>>1;
             51         if(X[mid]>=val) r = mid;
             52         else l = mid+1;
             53     }
             54     return l;
             55 }
             56 ll work(){
             57     int len = 0,k = 1;
             58     for(int i=0;i<n;i++){
             59         seg[len] = node(num[i][0],num[i][2],num[i][1]-1,1);
             60         X[len++] = num[i][0];
             61         seg[len] = node(num[i][0],num[i][2],num[i][3],-1);
             62         X[len++] = num[i][2];
             63     }
             64     sort(seg,seg+len);
             65     sort(X,X+len);
             66     for(int i=1;i<len;i++)
             67         if(X[i]!=X[i-1]) X[k++] = X[i];
             68     for(int i=k;i>=1;i--) X[i] = X[i-1];
             69     memset(lt,-1,sizeof(lt));
             70     memset(rt,-1,sizeof(rt));
             71     memset(cnt,0,sizeof(cnt));
             72     X[0] = 0; X[k+1] = w+1;
             73     update(0,0,1,0,k+1,1);
             74     update(k+1,k+1,1,0,k+1,1);
             75     ll last = cal(w,m);
             76     ll ans = last * seg[0].h;
             77     for(int i=0;i<len-1;i++){
             78         int l = search(seg[i].l,k+1);
             79         int r = search(seg[i].r,k+1);
             80         L = w+1, R = -1;
             81         update(l,r,1,0,k+1,seg[i].p);
             82         last -= seg[i].p * cal(X[L]-X[R]-1,m);
             83         last += seg[i].p * cal(X[L]-X[r]-1,m);
             84         last += seg[i].p * cal(X[l]-X[R]-1,m);
             85         ans += last * (seg[i+1].h - seg[i].h);
             86     }
             87     ans += cal(w,m) * (h - seg[len-1].h);
             88     return ans;
             89 }
             90 // main
             91 int main(){
             92     ll ans ;
             93     while(~scanf("%d%d%d%d",&w,&h,&n,&m)){
             94         for(int i=0;i<n;i++) for(int j=0;j<4;j++)
             95             scanf("%d",&num[i][j]);
             96         if(n==0) { 
             97             ans = h*cal(w,m) + w*cal(h,m);
             98             if(m == 1) cout<<ans/2<<endl;
             99             else cout<<ans<<endl;
            100             continue;
            101         }
            102         ans = work();
            103         swap(w,h);
            104         for(int i=0;i<n;i++){
            105             swap(num[i][0],num[i][1]);
            106             swap(num[i][2],num[i][3]);
            107         }
            108         ans += work();
            109         if(m==1)
            110             cout<<ans/2<<endl;
            111         else cout<<ans<<endl;
            112     }
            113 }
            114 
            posted on 2012-05-09 22:20 西月弦 閱讀(530) 評論(0)  編輯 收藏 引用 所屬分類: 解題報告
            久久精品中文字幕无码绿巨人| 一本久久久久久久| 亚洲欧洲精品成人久久奇米网| 久久久久久久91精品免费观看| 蜜臀av性久久久久蜜臀aⅴ麻豆| 久久国产高清字幕中文| 久久嫩草影院免费看夜色| 精品久久人人爽天天玩人人妻| 91精品国产高清91久久久久久| 欧美久久久久久午夜精品| 久久超碰97人人做人人爱| 久久精品18| 999久久久免费精品国产| 亚洲精品成人网久久久久久| 精品人妻久久久久久888| 亚洲精品无码专区久久同性男| 粉嫩小泬无遮挡久久久久久| 中文字幕无码久久人妻| 国产精品久久久久久久午夜片| 久久久久亚洲AV无码网站| 亚洲天堂久久久| 久久99精品久久久久久不卡| 99久久精品日本一区二区免费| 影音先锋女人AV鲁色资源网久久 | 久久久精品久久久久特色影视| 色偷偷88888欧美精品久久久| 99久久国产亚洲高清观看2024| 久久水蜜桃亚洲av无码精品麻豆| 久久伊人色| 久久免费99精品国产自在现线 | 亚洲精品乱码久久久久久久久久久久| 久久伊人五月天论坛| 精品久久久久久久久久中文字幕| 久久婷婷五月综合色奶水99啪| 欧美亚洲国产精品久久高清| 亚洲精品国产第一综合99久久| 久久精品国产WWW456C0M| 久久精品女人天堂AV麻| 久久精品国产99久久香蕉| 久久综合一区二区无码| 无码任你躁久久久久久老妇|