HDU-4533 威威猫系列故事——晒被子(区间更新)
题目大意:在平面直角坐标系的第一象限中,给出n个矩形(可能重叠)。有m次询问,每次询问点(t,t)的左下方的正方形区域中矩形的总面积(重叠部分重叠几次就得统计几次)。
题目分析:线段树的叶子节点x维护的是点(x,x)左下方的正方形区域中矩形的总面积。每添加一个矩形,便做一次区间更新。
代码如下:
# include<bits/stdc++.h> using namespace std; # define LL long long # define mid (l+(r-l)/2) const int N=200000; LL lazy[N*4+1]; LL lazy_a0[N*4+1],lazy_d[N*4+1]; LL lazy_a[N*4+1],lazy_b[N*4+1],lazy_c[N*4+1]; void read(int &x) { x=0; char c; while((c=getchar())&&(c<'0'||c>'9')); x=c-'0'; while(c=getchar()){ if(c<'0'||c>'9') break; x=x*10+c-'0'; } } void pushDown(int rt,int l,int r) { lazy[rt<<1]+=lazy[rt]; lazy[rt<<1|1]+=lazy[rt]; lazy[rt]=0; lazy_a0[rt<<1]+=lazy_a0[rt]; lazy_a0[rt<<1|1]+=lazy_a0[rt]+(LL)(mid-l+1)*lazy_d[rt]; lazy_d[rt<<1]+=lazy_d[rt]; lazy_d[rt<<1|1]+=lazy_d[rt]; lazy_a0[rt]=lazy_d[rt]=0; lazy_a[rt<<1]+=lazy_a[rt]; lazy_a[rt<<1|1]+=lazy_a[rt]; lazy_a[rt]=0; lazy_b[rt<<1]+=lazy_b[rt]; lazy_b[rt<<1|1]+=lazy_b[rt]; lazy_b[rt]=0; lazy_c[rt<<1]+=lazy_c[rt]; lazy_c[rt<<1|1]+=lazy_c[rt]; lazy_c[rt]=0; } void build(int rt,int l,int r) { lazy[rt]=0; lazy_a0[rt]=lazy_d[rt]=0; lazy_a[rt]=lazy_b[rt]=lazy_c[rt]=0; if(l==r) return ; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); } void update1(int rt,int l,int r,int L,int R,LL x) { if(L<=l&&r<=R){ lazy[rt]+=x; }else{ if(L<=mid) update1(rt<<1,l,mid,L,R,x); if(R>mid) update1(rt<<1|1,mid+1,r,L,R,x); } } void update2(int rt,int l,int r,int L,int R,LL a0,int d) { if(L<=l&&r<=R){ LL a1=(LL)a0+(LL)d*(LL)(l-L); lazy_a0[rt]+=(LL)a1; lazy_d[rt]+=(LL)d; }else{ if(L<=mid) update2(rt<<1,l,mid,L,R,a0,d); if(R>mid) update2(rt<<1|1,mid+1,r,L,R,a0,d); } } void update3(int rt,int l,int r,int L,int R,int lowx,int lowy) { if(L<=l&&r<=R){ ++lazy_a[rt]; lazy_b[rt]-=(LL)(lowx+lowy); lazy_c[rt]+=(LL)lowx*(LL)lowy; }else{ if(L<=mid) update3(rt<<1,l,mid,L,R,lowx,lowy); if(R>mid) update3(rt<<1|1,mid+1,r,L,R,lowx,lowy); } } LL query(int rt,int l,int r,int x) { if(l==r){ LL ans=0; ans+=lazy[rt]; LL last=lazy_a0[rt]+(r-l)*lazy_d[rt]; ans+=(r-l+1)*(lazy_a0[rt]+last)/2; ans+=lazy_a[rt]*l*l+lazy_b[rt]*l+lazy_c[rt]; return ans; }else{ pushDown(rt,l,r); if(x<=mid) return query(rt<<1,l,mid,x); return query(rt<<1|1,mid+1,r,x); } } int main() { int T,n; read(T); while(T--) { build(1,0,N); scanf("%d",&n); int x1,x2,y1,y2; while(n--){ scanf("%d%d%d%d",&x1,&y1,&x2,&y2); int dltx=x2-x1; int dlty=y2-y1; update1(1,0,N,max(x2,y2)+1,N,(LL)dltx*(LL)dlty); if(y1>=x2) update2(1,0,N,y1,y2,0,dltx); else if(y2<=x1) update2(1,0,N,x1,x2,0,dlty); else if(y2>x1&&y1<x2){ if(y2<x2&&y1<=x1){ update3(1,0,N,x1,y2-1,x1,y1); update2(1,0,N,y2,x2,(LL)dlty*(y2-x1),dlty); }else if(y2>=x2&&y1<=x1){ update3(1,0,N,x1,x2-1,x1,y1); update2(1,0,N,x2,y2,(LL)dltx*(LL)(x2-y1),dltx); }else if(y2>=x2&&y1>x1){ update3(1,0,N,y1,x2-1,x1,y1); update2(1,0,N,x2,y2,(LL)dltx*(x2-y1),dltx); }else if(y2<x2&&y1>x1){ update3(1,0,N,y1,y2-1,x1,y1); update2(1,0,N,y2,x2,(LL)dlty*(LL)(y2-x1),dlty); } } } scanf("%d",&n); while(n--) { scanf("%d",&x1); printf("%lld\n",query(1,0,N,x1)); } } return 0; }