zoukankan      html  css  js  c++  java
  • zoj 3540

      1 /*
      2 题意:给你n*m的棋盘,有些棋盘被一些矩形覆盖,求放进一个长为M,宽为1的矩形的方案数
      3 
      4 离散,线段树 +扫描线 
      5 分析:最直接得想法,对于每一层统计空白连续的长度然后统计放的方案数,不过编程复杂度有点高
      6 要分别记录下每个区间左边连续最长空白长度和右边最长连续空白长度,
      7 然后count[rt]=count[r<<1]+count[rt<<1|1]+{跨两段的个数} 
      8 
      9 一个好想法:当以y为分层标准时,统计竖着放的方案数,那么把每个矩形都向下延伸M-1个单位,
     10 那么剩下的每一个空位都对应一种方法,直接矩形并求面积就好,问题得到转化;
     11 
     12 一些细节:扫描线的细节处非常有意思;
     13 首先题目给我们的数据是对应一段区间的,比如矩形[2,2,2,2]表示长宽都为1的矩形,为了方便,我们把它转化成
     14 [1,1,2,2]这样在统计的时候直接相减就可以了, 
     15 */
     16 #include<cstdio>
     17 #include<cstring>
     18 #include<cstdlib>
     19 #include<iostream>
     20 #include<algorithm>
     21 #include<cmath>
     22 #include<vector>
     23 #include<set>
     24 #define lson l,m,rt<<1
     25 #define rson m+1,r,rt<<1|1
     26 #define Find(i) lower_bound(LX.begin(),LX.begin()+n1,i)-LX.begin()
     27 using namespace std;
     28 const int NN=100000+10;
     29 typedef long long LL;
     30 struct Edge{
     31     int hi,ls,rs,s;
     32     Edge(){}
     33     Edge(int a,int b,int c,int e):hi(a),ls(b),rs(c),s(e){}
     34     bool operator < (const Edge &p)const{
     35         return hi<p.hi;
     36     }
     37 }; 
     38 vector<Edge> E;
     39 vector<int> LX;
     40 int len[NN<<2],cov[NN<<2];
     41 int W,H,N,M,n1;
     42 int x[NN/2],y[NN/2],x2[NN/2],y2[NN/2];
     43 LL ans;
     44 void pushup(int l,int r,int rt){
     45     if (cov[rt]>=1){
     46         len[rt]=(LX[r+1]-LX[l]);
     47     }else if (l==r) len[rt]=0;
     48     else len[rt]=len[rt<<1]+len[rt<<1|1]; 
     49 }
     50 void update(int L,int R,int v,int l,int r,int rt){
     51     if (L<=l && r<=R){
     52         cov[rt]+=v;
     53         if (cov[rt]>=1) len[rt]=(LX[r+1]-LX[l]);
     54         else if (l==r) len[rt]=0;
     55         else len[rt]=len[rt<<1]+len[rt<<1|1];
     56         return ;
     57     }
     58     int m=(l+r)>>1;
     59     if (L<=m) update(L,R,v,lson);
     60     if (m< R) update(L,R,v,rson);
     61     pushup(l,r,rt);
     62 }
     63 
     64 void work(){
     65     E.clear();LX.clear();
     66     E.push_back(Edge(max(0,H-M+1),0,W,1));
     67     E.push_back(Edge(H,0,W,-1));
     68     LX.push_back(0);LX.push_back(W);//最后面要加入一个大矩形    
     69     for (int i=0;i<N;i++){
     70         E.push_back(Edge(max(0,y[i]-M),x[i]-1,x2[i],1));//矩形往下延伸 
     71         E.push_back(Edge(y2[i],x[i]-1,x2[i],-1));
     72         LX.push_back(x[i]-1);LX.push_back(x2[i]);
     73 
     74     }
     75     sort(E.begin(),E.end());
     76     sort(LX.begin(),LX.end());
     77     n1=unique(LX.begin(),LX.end())-LX.begin();
     78     
     79     LL ret=0;
     80     memset(len,0,sizeof(len));
     81     memset(cov,0,sizeof(cov));
     82 //    cout<<"**** "<<endl;
     83     for (int i=0;i<E.size();i++){
     84     //    cout<<E[i].hi<<" "<<E[i].ls<<" "<<E[i].rs<<" "<<E[i].s<<endl;
     85         int l=Find(E[i].ls),r=Find(E[i].rs)-1;
     86         if (l<=r) update(l,r,E[i].s,0,n1-1,1);
     87         if (E[i].hi!=E[i+1].hi){
     88         //    cout<<len[1]<<endl;
     89             ret+=(LL)len[1]*(E[i+1].hi-E[i].hi);
     90         }
     91     }
     92     ans+=(LL)W*H-ret;
     93 }
     94 int main(){
     95     while (~scanf("%d%d%d%d",&W,&H,&N,&M)){
     96         for (int i=0;i<N;i++){
     97             scanf("%d%d%d%d",x+i,y+i,x2+i,y2+i);
     98         }
     99         ans=0;
    100         work();
    101         if (M!=1) {
    102             swap(H,W);
    103             for (int i=0;i<N;i++){
    104                 swap(x[i],y[i]);swap(x2[i],y2[i]);
    105             }
    106             work();
    107         }
    108         printf("%lld\n",ans);
    109     }
    110 }
  • 相关阅读:
    [NoiPlus2016]天天爱跑步
    POJ3539 Elevator
    CodeForces 37E Trial for Chief
    CodeForces 986C AND Graph
    [tyvj-2054][Nescafé29]四叶草魔杖 费用流
    [CodeForces]986A Fair
    [CodeForces]981C Useful Decomposition
    分配问题
    圆桌问题
    数字梯形问题
  • 原文地址:https://www.cnblogs.com/Rlemon/p/3099833.html
Copyright © 2011-2022 走看看