这个每一个矩形都确定了一个不能放的矩形空间,那么就是可以转化成求矩形面积并了。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <set> #define ll long long #define midt (tr[t].l+tr[t].r>>1) #define ls t<<1 #define rs t<<1|1 using namespace std; const int maxn=7e4+9; int w,h,n,m; int y[maxn<<2],lon; struct { int xl,xu,yl,yu; }rec[maxn],now[maxn<<1]; struct D { int x,y1,y2,count; bool operator <(const D &xx) const { if(x!=xx.x) return(x<xx.x); else return count>xx.count; } }d[maxn<<1]; struct { int l,r,y1,y2,count,len; }tr[maxn<<5]; void maketree(int t,int l,int r) { tr[t].l=l; tr[t].r=r; tr[t].y1=y[l]; tr[t].y2=y[r]; tr[t].len=0; tr[t].count=0; if(l+1==r) return ; int mid=midt; maketree(ls,l,mid); maketree(rs,mid,r); } void insert(int t,int y1,int y2,D &d) { if(tr[t].y1==y1&&tr[t].y2==y2) { tr[t].count+=d.count; } else { int mid=midt; if(y2<=y[mid]) insert(ls,y1,y2,d); else if(y[mid]<=y1) insert(rs,y1,y2,d); else { insert(ls,y1,y[mid],d); insert(rs,y[mid],y2,d); } } if(tr[t].count>0) tr[t].len=tr[t].y2-tr[t].y1; else if(tr[t].l+1==tr[t].r) tr[t].len=0; else tr[t].len=tr[ls].len+tr[rs].len; } ll solve() { set <int> s; s.clear(); for(int i=1;i<=n;i++) { d[i*2-1].x=now[i].xl; d[i*2-1].y1=now[i].yl; d[i*2-1].y2=now[i].yu; d[i*2-1].count=1; d[i*2].x=now[i].xu; d[i*2].y1=now[i].yl; d[i*2].y2=now[i].yu; d[i*2].count=-1; s.insert(now[i].yl); s.insert(now[i].yu); } lon=0; for(set <int> ::iterator k=s.begin();k!=s.end();k++) { y[++lon]=*k; } if(lon==0) return 0; sort(d+1,d+1+n+n); maketree(1,1,lon); ll ans=0; d[0].x=-1; for(int i=1;i<=n*2;i++) { if(d[i].y1<=d[i].y2) { ans+=(ll)(d[i].x-d[i-1].x)*tr[1].len; insert(1,d[i].y1,d[i].y2,d[i]); } } return ans; } int main() { // freopen("in.txt","r",stdin); while(scanf("%d%d%d%d",&w,&h,&n,&m)!=EOF) { for(int i=1;i<=n;i++) { scanf("%d%d",&rec[i].xl,&rec[i].yl); scanf("%d%d",&rec[i].xu,&rec[i].yu); rec[i].xl--; rec[i].yl--; } for(int i=1;i<=n;i++) { now[i].xl=max(0,rec[i].xl-m+1); now[i].xu=min(rec[i].xu,w-m+1); now[i].yl=rec[i].yl; now[i].yu=rec[i].yu; } ll ret=0; if(w-m+1>0) ret+=solve(); for(int i=1;i<=n;i++) { now[i].xl=rec[i].xl; now[i].xu=rec[i].xu; now[i].yl=max(0,rec[i].yl-m+1); now[i].yu=min(rec[i].yu,h-m+1); } if(h-m+1>0) ret+=solve(); ret=max((ll)(w-m+1)*h,(ll)0)+max((ll)w*(h-m+1),(ll)0)-ret; if(m==1) ret/=2; cout<<ret<<endl; } return 0; }