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; }