洛谷p5490線段樹掃描線+離散化
阿新 • • 發佈:2022-01-10
P5490 【模板】掃描線
這題線段樹的節點表示的是區間,樹上節點x表示的區間【l,r】是實際點的[l,r+1]區間;因為我們純用點一一對應
當標記落到一個點時 沒有任何意義;標記更新,如果當前節點被標記,說明區間被標記,如果當前節點沒被標記,返回左節點和右節點被標記的總長度
sum[x]維護的是節點為X ,l-r區間被標記的線段長度;
1 #include<bits/stdc++.h> 2 #define ls (x<<1) 3 #define rs (x<<1|1) 4 using namespace std; 5 typedef long longll; 6 const int N=8e5+5; 7 int n,tot; 8 ll xbin[N<<1],ybin[N<<1],sum[N<<2],tag[N<<2]; 9 struct matrix 10 { 11 int x1,y1,x2,y2; 12 }a[N]; 13 struct event 14 { 15 int val,x1,x2; 16 }; 17 vector<event>e[N<<1]; 18 19 void build(int l,int r,int x) 20 {21 if(l==r)return; 22 int mid=(l+r)>>1; 23 build(l,mid,ls); 24 build(mid+1,r,rs); 25 } 26 void update(int l,int r,int x) 27 { 28 if(tag[x])sum[x]=xbin[r+1]-xbin[l]; 29 else sum[x]=sum[ls]+sum[rs]; 30 } 31 32 void modify(int A,int B,int l,int r,int v,int x) 33 { 34 if(A<=l&&r<=B) 35 { 36 tag[x]+=v; 37 update(l,r,x); 38 return ; 39 } 40 int mid=(l+r)>>1; 41 if(A<=mid)modify(A,B,l,mid,v,ls); 42 if(B>mid)modify(A,B,mid+1,r,v,rs); 43 update(l,r,x); 44 } 45 46 int main() 47 { 48 scanf("%d",&n); 49 for(int i=1;i<=n;i++) 50 { 51 int x1,y1,x2,y2; 52 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 53 a[i].x1=x1;a[i].y1=y1;a[i].x2=x2;a[i].y2=y2; 54 xbin[++tot]=x1,ybin[tot]=y1; 55 xbin[++tot]=x2,ybin[tot]=y2; 56 } 57 sort(xbin+1,xbin+1+tot); 58 sort(ybin+1,ybin+1+tot); 59 int cntx=unique(xbin+1,xbin+1+tot)-xbin-1; 60 int cnty=unique(ybin+1,ybin+1+tot)-ybin-1; 61 62 for(int i=1;i<=n;i++) 63 { 64 int ey1=lower_bound(ybin+1,ybin+cnty+1,a[i].y1)-ybin; 65 int ey2=lower_bound(ybin+1,ybin+cnty+1,a[i].y2)-ybin; 66 int ex1=lower_bound(xbin+1,xbin+cntx+1,a[i].x1)-xbin; 67 int ex2=lower_bound(xbin+1,xbin+cntx+1,a[i].x2)-xbin; 68 e[ey1].push_back({1,ex1,ex2}); 69 e[ey2].push_back({-1,ex1,ex2}); 70 } 71 ll ans=0; 72 ybin[0]=ybin[1]; 73 build(1,cntx,1); 74 for(int i=1;i<=cnty;i++) 75 { 76 ans+=sum[1]*(ybin[i]-ybin[i-1]); 77 for(int j=0;j<e[i].size();j++) 78 { 79 int v=e[i][j].val,l=e[i][j].x1,r=e[i][j].x2; 80 modify(l,r-1,1,cntx,v,1); 81 } 82 } 83 cout<<ans<<endl; 84 return 0; 85 }