思路就是把被子拆成4个点,如果某个点(x,y)在(0,0)-(t,t)内的话,如果这个点是左下角或者右上角 面积就+=(t-x)*(t-y),反之面积-=(t-x)*(t-y);(画个图就知道了)
而(t-x)*(t-y) = t*t-(x+y)*t+x*y
所以,需要维护3个系数1,-(x+y),x*y;
在代码中体现
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <climits>
#include <ctime>
#include <numeric>
#include <vector>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <complex>
#include <deque>
#include <functional>
#include <list>
#include <map>
#include <string>
#include <sstream>
#include <set>
#include <stack>
#include <queue>
using namespace std;
template<class T> inline T sqr(T x) { return x * x; }
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<PII, int> PIII;
typedef pair<LL, LL> PLL;
typedef pair<LL, int> PLI;
typedef pair<LD, LD> PDD;
#define MP make_pair
#define PB push_back
#define sz(x) ((int)(x).size())
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define istr stringstream
#define FOR(i,n) for(int i=0;i<(n);++i)
const double EPS = 1e-6;
const int INF = 0x3fffffff;
const LL LINF = INF * 1ll * INF;
const double PI = acos(-1.0);
using namespace std;
int t;
int n;
struct point{
LL x,y;
bool operator<(const point& p) const{
return max(x,y)<max(p.x,p.y);
}
LL getT(){
return max(x,y);
}
} p_a[40001],p_b[40001];//p_a表示左下角或者右上角的点,p_b表示左上角或右下角的点
inline bool isDigit(char c){
return c<='9'&&c>='0';
}
LL& getVal(LL & num){
num = 0ll;
char c = getchar();
while(!isDigit(c)) c = getchar();
while(isDigit(c)){
num = num*10+c-'0';
c = getchar();
}
return num;
}
inline point getP(int x,int y){
point p;
p.x = x;
p.y = y;
return p;
}
int main(void){
//freopen("","r",stdin);
scanf("%d",&t);
while(t--){
scanf("%d",&n);
LL x1,y1,x2,y2;
int a_cnt = 0,b_cnt = 0;
for(int i = 0;i<n;i++){
getVal(x1);
getVal(y1);
getVal(x2);
getVal(y2);
p_a[a_cnt++] = getP(x1,y1);
p_a[a_cnt++] = getP(x2,y2);
p_b[b_cnt++] = getP(x2,y1);
p_b[b_cnt++] = getP(x1,y2);
}
sort(p_a,p_a+a_cnt);
sort(p_b,p_b+b_cnt);
//t:t*t-(x1+x2)*t+x1*x2
int q;
scanf("%d",&q);
int a_i = 0,b_i = 0;
LL a1 = 0,b1 = 0,c1 = 0,a2 = 0,b2 = 0,c2 = 0;
while(q--){
LL tt;
getVal(tt);
while(true){
if(a_i<2*n&&p_a[a_i].getT()<=tt){
a1++;
b1+=p_a[a_i].x+p_a[a_i].y;
c1+=p_a[a_i].x*p_a[a_i].y;
a_i++;
}else break;
}
while(true){
if(b_i<2*n&&p_b[b_i].getT()<=tt){
a2++;
b2+=p_b[b_i].x+p_b[b_i].y;
c2+=p_b[b_i].x*p_b[b_i].y;
b_i++;
}else break;
}
printf("%I64d\n",tt*tt*(a1-a2)-tt*(b1-b2)+(c1-c2));
}
}
}