/*
把(0,0),(t,t)看成是一个大矩形的话,那么这个大矩形的右上坐标x是等于y的,有了这个就好办了,
我们可以维持一颗关于t的线段树,比如现在对一个X矩形(x1,y1),(x2,y2)来说如果t>=Max(x2,y2),那么这个面积直接加上;
在关于t的这颗线段树上操作也就是相当于更新(Max(x2,y2)~Max(t))这个区间,而对于(0~MAx(x1,y1))这个区间是无影响的;
现在在于怎么处理MAx(x1,y1)~Min(x2,y2)和Max(MAx(x1,y1),Min(x2,y2))~Max(x2,y2)这两个区间
如果Max(x1,y1)<Min(x2,y2),那么这端区间和X矩形的相交的面积就是(t-x1)*(t-y1);而这里t是变动的,
所以我把式子变一下得t*t-(x1+y1)*t+x1*y1,这样我们可以开三个数组保存这个方程的系数(1,-(x1+y1),x1*y1),
因为这三个系数是常数并且可以进行加减运算,然后一样可以利用线段树的lazy思想,系数到最后再计算是一样的。
用类似的方法去处理Max(MAx(x1,y1),Min(x2,y2))~Max(x2,y2)这个区间,画个图就明白了;
对于Max(MAx(x1,y1),Min(x2,y2))~Max(x2,y2)这个区间处理有两种情况(如下图,手画的,只能看个大概):
这是第一种情况(y2>x2):
重叠面积为(t-x1)*(t-y1)-(t-x2)*(t-y1)展开为:(-x1-y1+y1+x2)*t+y1*(x1-x2);和前面一样在线段树区间上更新这个方程的系数
第二种情况(x2>y2):
重叠面积为(t-x1)*(t-y1)-(t-x1)*(t-y2)展开为:(-x1-y1+x1+y2)*t+x1*(y1-y2);和前面一样在线段树区间上更新这个方程的系数
上面的介绍体现在POP函数里面,主要的思想是利用保存系数达到目的;
今天比赛太挫了,A题弄了我好久wa了好几次,D题也没在比赛的时候过,太悲剧了;
*/
#include<stdio.h>
#include<string.h>
#define _LL __int64
int n=200000;
_LL A[800000],B[800000],C[800000];
void update(int i,int l,int r,int a,int b,_LL *v)
{
int mid;
if(a>b) return;
if(a==l&&r==b)
{
A[i]+=v[0];B[i]+=v[1];C[i]+=v[2];
return ;
}
mid=(l+r)/2;
if(b<=mid) update(i<<1,l,mid,a,b,v);
else if(a>mid) update(i<<1|1,mid+1,r,a,b,v);
else {
update(i<<1,l,mid,a,mid,v);
update(i<<1|1,mid+1,r,mid+1,b,v);
}
}
_LL query(int i,int l,int r,_LL p)
{
int mid;
if(l==r) return p*p*A[i]+p*B[i]+C[i];
mid=(l+r)/2;
A[i<<1]+=A[i];B[i<<1]+=B[i];C[i<<1]+=C[i];
A[i<<1|1]+=A[i];B[i<<1|1]+=B[i];C[i<<1|1]+=C[i];
A[i]=B[i]=C[i]=0;
if(p<=mid) return query(i<<1,l,mid,p);
else return query(i<<1|1,mid+1,r,p);
}
void POP(_LL a,_LL b,_LL x,_LL y)
{
int m=a<b?b:a,t=x>y?x:y,t2=x>y?y:x;
_LL v[3]={0,0,0};
v[2]=(x-a)*(y-b);
update(1,1,n,t+1,n,v);
v[0]=1;v[1]=-(a+b);v[2]=a*b;
if(t2>=m) update(1,1,n,m+1,t2,v);
if(y>x){
v[0]-=1;
v[1]+=x+b;v[2]-=x*b;
}
else if(x>y)
{
v[0]-=1;
v[1]+=a+y;v[2]-=a*y;
}
if(m>t2) t2=m;
update(1,1,n,t2+1,t,v);
}
int main()
{
int cas,m,i;
_LL x1,x2,y1,y2;
scanf("%d",&cas);
while(cas--)
{
memset(A,0,sizeof(A));
memset(B,0,sizeof(B));
memset(C,0,sizeof(C));
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2);
POP(x1,y1,x2,y2);
}
scanf("%d",&m);
while(m--)
{
scanf("%I64d",&x1);
printf("%I64d\n",query(1,1,n,x1));
}
}
return 0;
}