题目描述
分析
存一下板子,注意线段树维护的是左闭右开的区间
代码
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define rg register
inline int read(){
rg int x=0,fh=1;
rg char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') fh=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*fh;
}
const int maxn=1e6+5;
int n,sta[maxn],tp=0,js=0,rk[maxn];
long long ans;
struct jie{
int val,l,r,op;
jie(){}
jie(int aa,int bb,int cc,int dd){
val=aa,l=bb,r=cc,op=dd;
}
}b[maxn];
bool cmp(jie aa,jie bb){
return aa.val<bb.val;
}
struct trr{
int l,r,cnt,len;
}tr[maxn<<2];
void push_up(int da){
if(tr[da].cnt) tr[da].len=sta[tr[da].r+1]-sta[tr[da].l];
else tr[da].len=tr[da<<1].len+tr[da<<1|1].len;
}
void build(int da,int l,int r){
tr[da].l=l,tr[da].r=r;
if(tr[da].l==tr[da].r){
tr[da].cnt=tr[da].len=0;
return;
}
rg int mids=(tr[da].l+tr[da].r)>>1;
build(da<<1,l,mids);
build(da<<1|1,mids+1,r);
}
void xg(int da,int l,int r,int val){
if(tr[da].l>=l && tr[da].r<=r){
tr[da].cnt+=val;
push_up(da);
return;
}
rg int mids=(tr[da].l+tr[da].r)>>1;
if(l<=mids) xg(da<<1,l,r,val);
if(r>mids) xg(da<<1|1,l,r,val);
push_up(da);
}
int main(){
n=read();
rg int aa,bb,cc,dd;
for(rg int i=1;i<=n;i++){
aa=read(),bb=read(),cc=read(),dd=read();
b[++js]=jie(aa,bb,dd,1);
b[++js]=jie(cc,bb,dd,-1);
sta[++tp]=bb;
sta[++tp]=dd;
}
std::sort(sta+1,sta+tp+1);
tp=std::unique(sta+1,sta+tp+1)-sta-1;
for(rg int i=1;i<=n*2;i++){
b[i].l=std::lower_bound(sta+1,sta+1+tp,b[i].l)-sta;
b[i].r=std::lower_bound(sta+1,sta+1+tp,b[i].r)-sta;
}
std::sort(b+1,b+1+n*2,cmp);
build(1,1,tp);
b[n*2+1]=b[n*2];
for(rg int i=1;i<=n*2;i++){
xg(1,b[i].l,b[i].r-1,b[i].op);
ans+=1LL*tr[1].len*(b[i+1].val-b[i].val);
}
printf("%lld
",ans);
return 0;
}