uva 11983 求矩形覆盖k次以上的面积并

k很小,每个可以保存覆盖0~k次的区间和,k次以上全算k次,可以做模板了

View Code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long lld;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 60000;
int sum[maxn<<2][15];
int cov[maxn<<2];
int x[maxn];
int n,m;
struct seg{
    int l,r,h;
    int flag;
    seg(){}
    seg(int _l,int _r,int _h,int _flag):l(_l),r(_r),h(_h),flag(_flag){}
    bool operator < (const seg &cmp) const {
        return h<cmp.h;
    }
}ss[maxn];
void pushup(int rt,int l,int r){
    if(cov[rt]>=m || l==r){
         memset(sum[rt],0,sizeof(sum[rt]));
         int t=cov[rt] < m ? cov[rt] : m;
         sum[rt][t]=x[r+1]-x[l];
         return ;
     }
     int i;
     for(i=0;i<cov[rt];i++) sum[rt][i]=0;
     for(i=cov[rt];i<m;i++)
         sum[rt][i]=sum[rt<<1][i-cov[rt]]+sum[rt<<1|1][i-cov[rt]];
     sum[rt][m]=0;
     for(i=m-cov[rt];i<=m;i++)
         sum[rt][m]+=sum[rt<<1][i]+sum[rt<<1|1][i];
}
void build(int l,int r,int rt){
    cov[rt]=0;sum[rt][0]=x[r+1]-x[l];
    for(int i=1;i<=m;i++) sum[rt][i]=0;
    if(l==r)   return ;
    int m=(l+r)>>1;
    build(lson);build(rson);
}
void update(int L,int R,int val,int l,int r,int rt){
    if(L<=l&&r<=R){
        cov[rt]+=val;
        pushup(rt,l,r);
        return ;
    }
    int m=(l+r)>>1;
    if(L<=m) update(L,R,val,lson);
    if(R>m) update(L,R,val,rson);
    pushup(rt,l,r);
}
int main(){
    int t,ca=1,i,j,k,x1,x2,y1,y2;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        int tot=0;
        for(i=1;i<=n;i++){
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);x2++;y2++;
            x[tot]=x1;
            ss[tot++]=seg(x1,x2,y1,1);
            x[tot]=x2;
            ss[tot++]=seg(x1,x2,y2,-1);
        }
        sort(x,x+tot);
        sort(ss,ss+tot);
        int nx=unique(x,x+tot)-x;
        build(0,nx-1,1);//printf("%d\n",sum[1][0]);
        lld ans=0;
        for(i=0;i<tot-1;i++){
            int left=lower_bound(x,x+nx,ss[i].l)-x;
            int right=lower_bound(x,x+nx,ss[i].r)-x-1;
            update(left,right,ss[i].flag,0,nx-1,1);
            ans+=(lld)sum[1][m]*(lld)(ss[i+1].h-ss[i].h);
        }
        printf("Case %d: %lld\n",ca++,ans);
    }
    return 0;
}

 

posted @ 2012-06-03 09:29  Because Of You  Views(585)  Comments(0Edit  收藏  举报