洛谷p5490线段树扫描线+离散化

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 long ll;
 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 }

 

posted @ 2022-01-10 21:06  matt-11  阅读(49)  评论(0)    收藏  举报