每个矩形提出其 左边 和 右边 , 每条边都使用三元组 表示, 放置对应的 坐标上,
使用一条 扫描线 从左向右扫, 如下图计算 橙色询问矩形 的答案,
计算相交面积 时, 考虑使用 总相交面积 减去 相交 不相交面积 .
可以在 询问矩形 右边 通过查询 的面积和得到 .
使用前面 黄色虚线面积 减去 绿色面积 得到 .
区间树状数组 :
区间查询: , .
于是 维护 ,
区间修改 :
对 差分, 处 , 处 .
对 差分, 处 , 处 .
#include<bits/stdc++.h>
#define reg register
typedef long long ll;
int read(){
char c;
int s = 0, flag = 1;
while((c=getchar()) && !isdigit(c))
if(c == '-'){ flag = -1, c = getchar(); break ; }
while(isdigit(c)) s = s*10 + c-'0', c = getchar();
return s * flag;
}
const int maxn = 5e5 + 5;
int N;
int M;
int W;
int L;
int cnt;
ll Ans[maxn];
struct Sgment{ int x, l, r, flag, id; } A[maxn<<2];
bool cmp(Sgment a, Sgment b){ return a.x < b.x; }
struct Bit_Tree{
int lim;
ll d[maxn], d2[maxn];
void Add(int k, ll x){
for(reg int i = k; i <= lim; i += (i&-i)) d[i] += x, d2[i] += 1ll*x*k;
}
ll Ask(int k){
if(k <= 0) return 0;
ll s = 0;
for(reg int i = k; i; i -= (i&-i)) s += (1ll*k+1)*d[i] - d2[i];
return s;
}
void modify(const int &l, const int &r, const ll &x){ Add(l, x), Add(r+1, -x); }
ll query(const int &l, const int &r){ return Ask(r) - Ask(l-1); }
} bit_t[2];
int main(){
N = read(), M = read(), W = read(), L = read();
for(reg int i = 1; i <= N; i ++){
int x1 = read(), y1 = read(), x2 = read(), y2 = read();
A[++ cnt] = (Sgment){ x1, y1+1, y2, 1, 0 };
A[++ cnt] = (Sgment){ x2, y1+1, y2, -1, 0 };
}
for(reg int i = 1; i <= M; i ++){
int x1 = read(), y1 = read(), x2 = read(), y2 = read();
A[++ cnt] = (Sgment){ x1, y1+1, y2, -1, i };
A[++ cnt] = (Sgment){ x2, y1+1, y2, 1, i };
}
bit_t[0].lim = bit_t[1].lim = L;
std::sort(A+1, A+cnt+1, cmp);
for(reg int i = 0, j = 1; i <= W; i ++){
while(A[j].x == i){
if(!A[j].id){
bit_t[1].modify(A[j].l, A[j].r, 1ll*A[j].flag*i);
bit_t[0].modify(A[j].l, A[j].r, A[j].flag);
}else{
ll s1 = bit_t[1].query(A[j].l, A[j].r);
ll s2 = bit_t[0].query(A[j].l, A[j].r);
Ans[A[j].id] += 1ll*A[j].flag*(1ll*i*s2 - s1);
}
j ++;
}
}
for(reg int i = 1; i <= M; i ++) printf("%lld
", Ans[i]);
return 0;
}