具体参考
其实是建立一个T的线段树,然而不同矩形对于不同的T会有三种形态。
讲这些面积用t的表达式算出来 会发现最后的面积是一个关于t的一元二次方程
最后维护这个方程的三个系数,从而达到求解。
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define maxn 200005 #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e #define eps 1e-12 typedef long long LL; using namespace std; int n=maxn-5; LL A[maxn<<2],B[maxn<<2],C[maxn<<2]; void pushdown(int num) { A[num<<1]+=A[num];A[num<<1|1]+=A[num]; B[num<<1]+=B[num];B[num<<1|1]+=B[num]; C[num<<1]+=C[num];C[num<<1|1]+=C[num]; A[num]=B[num]=C[num]=0; } LL query(int num,int s,int e,LL pos) { if(s==e) { return pos*pos*A[num]+B[num]*pos+C[num]; } int mid=(s+e)>>1; pushdown(num); if(pos<=mid)return query(lson,pos); else return query(rson,pos); } void update(int num,int s,int e,int l,int r,LL a,LL b,LL c) { if(l<=s && r>=e) { A[num]+=a; B[num]+=b; C[num]+=c; return; } int mid=(s+e)>>1; if(l<=mid)update(lson,l,r,a,b,c); if(r>mid)update(rson,l,r,a,b,c); } void work(LL x1,LL y1,LL x2,LL y2) { LL a=0,b=0,c=0; update(1,1,n,max(x2,y2)+1,n,0,0,(x2-x1)*(y2-y1));//如果T==5的时候 s=10 那么 T==10的时候 s也应该等于10 这个就是更新后面的区域 if(x2<y2) { update(1,1,n,max(x2,y1)+1,y2,0,-x1+x2,y1*(x1-x2)); } else { update(1,1,n,max(y2,x1)+1,x2,0,-y1+y2,x1*(y1-y2)); } if(max(x1,y1)<min(x2,y2))//这个是第一种情况 update(1,1,n,max(x1,y1),min(x2,y2),1,-(x1+y1),x1*y1); } int main() { int T; scanf("%d",&T); while(T--) { int m; scanf("%d",&m); memset(A,0,sizeof A); memset(B,0,sizeof B); memset(C,0,sizeof C); while(m--) { LL x1,y1,x2,y2; scanf("%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2); work(x1,y1,x2,y2); } scanf("%d",&m); while(m--) { LL pos;//这里一定要定义为ll 不然会越界。 scanf("%I64d",&pos); printf("%I64d\n",query(1,1,n,pos)); } } return 0; }
hdu 4533 威威猫系列故事——晒被子(线段树 成端更新),布布扣,bubuko.com
hdu 4533 威威猫系列故事——晒被子(线段树 成端更新)
原文:http://blog.csdn.net/u010709592/article/details/20959473