题意:给出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|1
void 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;
}