求 \(n\) 个矩形的面积并
Solution
将矩形转化为 \(y_1\) 位置的 +
修改 和 \(y_2\) 位置的 -
修改。然后按照 \(+y\) 顺序依次处理所有的修改,到达的一个新的位置就算一下上一段的总贡献。
至于线段树,要么对 \(x\) 坐标离散化,要么动态开点。 我觉得后者比较快乐。
注意这里的标记没有必要下传
#include
using namespace std;
const int N = 5000005;
struct event{
int x1,x2,y,z;
bool operator < (const event &b) {
return y < b.y;
}
} e[N];
int n,m,a[N],cnt[N],tag[N],ch[N][2],ind=1;
void pushup(int p,int l,int r) {
if(p==0) return;
a[0]=0;
if(cnt[p]) a[p]=r-l+1;
else a[p]=a[ch[p][0]]+a[ch[p][1]];
}
void modify(int p,int l,int r,int ql,int qr,int c) {
if(l>qr||r=ql&&r<=qr) {
cnt[p]+=c;
pushup(p,l,r);
}
else {
if(ch[p][0]==0) ch[p][0]=++ind;
if(ch[p][1]==0) ch[p][1]=++ind;
modify(ch[p][0],l,(l+r)/2,ql,qr,c);
modify(ch[p][1],(l+r)/2+1,r,ql,qr,c);
pushup(p,l,r);
}
}
signed main() {
scanf("%d",&n);
for(int i=1;i<=n;i++) {
int x1,x2,y1,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
++x1; ++x2;
e[i*2-1]=(event){x1,x2,y1,1};
e[i*2]=(event){x1,x2,y2,-1};
m=max(m,x2);
}
sort(e+1,e+2*n+1);
long long ans=0;
for(int i=1;i<=2*n;i++) {
if(e[i].y!=e[i-1].y) ans+=1ll*a[1]*(e[i].y-e[i-1].y);
modify(1,1,m,e[i].x1+1,e[i].x2,e[i].z);
}
cout<