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;

}

 

你可能感兴趣的:(uva)