洛谷 P5490 【模板】掃描線
阿新 • • 發佈:2020-10-22
題目描述
分析
存一下板子,注意線段樹維護的是左閉右開的區間
程式碼
#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\n",ans); return 0; }