UVA 11893 Weird Advertisement(K次面价交)

来源:互联网 发布:mysql 索引失效 编辑:程序博客网 时间:2024/06/06 12:47

传送门:UVA 11893 Weird Advertisement


题意:给出N个矩形,求被这些矩形覆盖K次以上的区域面积。(K<=10,n<=3e4)


思路:类似于Hdu 1255 面积交


#include<bits/stdc++.h>using namespace std;const int N=6e4+100;struct node{    int l,r,h,d;}a[N*2];int mark[8*N],k,t[2*N];long long Time[8*N][11];bool cmp(node u,node v){    if(u.h==v.h)        return u.d>v.d;    return u.h<v.h;}#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1void build(int l,int r,int rt){    for(int i=0;i<=k;i++)        Time[rt][i]=0;    mark[rt]=0;    if(l==r)        return ;    int m=(l+r)>>1;    build(lson);    build(rson);}void pushup(int rt,int l,int r){    if(mark[rt]>=k){        for(int i=1;i<=k;i++)            Time[rt][i]=t[r+1]-t[l];    }    else if(mark[rt]>=1){        for(int i=1;i<=k;i++){            if(i<=mark[rt])                Time[rt][i]=t[r+1]-t[l];            else{                if(l==r)    //这样写节省空间,而且不需要memset初始化                    Time[rt][i]=0;                else                    Time[rt][i]=Time[rt<<1][i-mark[rt]]+Time[rt<<1|1][i-mark[rt]];            }        }    }    else{        if(l==r){            for(int i=1;i<=k;i++)                Time[rt][i]=0;        }        else{            for(int i=1;i<=k;i++)                Time[rt][i]=Time[rt<<1][i]+Time[rt<<1|1][i];        }    }}int L,R,d;void update(int l,int r,int rt){    if(L<=l&&R>=r){        mark[rt]+=d;        pushup(rt,l,r);        return ;    }    int m=(l+r)>>1;    if(L<=m)    update(lson);    if(R>m)     update(rson);    pushup(rt,l,r);}int main(){    int _,n;    scanf("%d",&_);    for(int case1=1;case1<=_;case1++){        scanf("%d%d",&n,&k);        int x1,y1,x2,y2;        for(int i=1;i<=n;i++){            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);            x1--,y1--;            a[i*2-1]=(node){x1,x2,y1,1};            a[i*2]=(node){x1,x2,y2,-1};            t[i*2-1]=x1,t[i*2]=x2;        }        sort(t+1,t+2*n+1);        int m=unique(t+1,t+2*n+1)-t-1;        t[m+1]=t[m];        long long ans=0;        sort(a+1,a+2*n+1,cmp);        build(1,m,1);        for(int i=1;i<2*n;i++){            L=lower_bound(t+1,t+m+1,a[i].l)-t,R=lower_bound(t+1,t+m+1,a[i].r)-t-1,d=a[i].d;            if(L<=R){                update(1,m,1);                ans+=Time[1][k]*(a[i+1].h-a[i].h);            }        }        printf("Case %d: %lld\n",case1,ans);    }    return 0;}
0 0
原创粉丝点击