扫描线_c++

 

 

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const ll N=1e5+11,M=2e5+11,Tree_Sz=2e6+11;
 5 ll n,xx[N][2],yy[N][2];
 6 ll num,b[M],Seg;
 7 
 8 inline ll re_ad() {
 9     char ch=getchar(); ll x=0,f=1;
10     while(ch<'0' || ch>'9') { if(ch=='-') f=-1;ch=getchar(); }
11     while('0'<=ch && ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
12     return x*f;
13 }
14 
15 struct Segment {
16     ll x,y,ht,v;
17     inline bool operator < (const Segment &B) const {
18         return ht<B.ht;
19     }
20 }seg[M];
21 
22 inline void addseg(ll ht,ll x,ll y,ll v) {
23     seg[++Seg]=(Segment){x,y,ht,v};
24 }
25 
26 struct SegmentTree {
27     struct Node {
28         ll cnt,sum,val;
29     }t[Tree_Sz];
30     inline void Pushup(ll d,ll l,ll r) {
31         if(t[d].cnt>=1) t[d].sum=t[d].val;
32         else t[d].sum=t[d<<1].sum+t[d<<1|1].sum;
33     }
34     void build(ll d,ll l,ll r) {
35         if(l==r) {
36             t[d].val=b[r+1]-b[l];
37             return ;
38         }
39         ll mid=(l+r)>>1;
40         build(d<<1,l,mid);
41         build(d<<1|1,mid+1,r);
42         t[d].val=t[d<<1].val+t[d<<1|1].val;
43     }
44     inline void Build() {
45         build(1,1,num-1);
46     }
47     void modify(ll d,ll l,ll r,ll x,ll y,ll z) {
48         if(x<=b[l] && b[r+1]<=y) {
49             t[d].cnt+=z,Pushup(d,l,r);
50             return ;
51         }
52         ll mid=(l+r)>>1;
53         if(x<=b[mid]) modify(d<<1,l,mid,x,y,z);
54         if(y>b[mid+1]) modify(d<<1|1,mid+1,r,x,y,z);
55         Pushup(d,l,r);
56     }
57     inline void Modify(ll x,ll y,ll z) {
58         modify(1,1,num-1,x,y,z);
59     }
60     inline ll Query() {
61         return t[1].sum;
62     }
63     void search(ll d,ll l,ll r) {
64         printf("%lld %lld %lld %lld %lld %lld\n",d,l,r,t[d].val,t[d].cnt,t[d].sum);
65         if(l==r) return ;
66         ll mid=(l+r)>>1;
67         search(d<<1,l,mid),search(d<<1|1,mid+1,r);
68     }
69 }st;
70 
71 int main()
72 {
73     n=re_ad();
74     for(ll i=1;i<=n;++i) xx[i][0]=re_ad(),yy[i][0]=re_ad(),xx[i][1]=re_ad(),yy[i][1]=re_ad();
75     for(ll i=1;i<=n;++i) b[i*2-1]=xx[i][0],b[i*2]=xx[i][1];
76     sort(b+1,b+n*2+1);
77     num=unique(b+1,b+n*2+1)-b-1;
78 //    for(int i=1;i<=n;++i) xx[i][0]=lower_bound(b+1,b+num+1,xx[i][0])-b,xx[i][1]=lower_bound(b+1,b+num+1,xx[i][1])-b;
79     st.Build();
80     for(int i=1;i<=n;++i) addseg(yy[i][0],xx[i][0],xx[i][1],1),addseg(yy[i][1],xx[i][0],xx[i][1],-1);
81 //    for(ll i=1;i<=n*2;++i) printf("%lld %lld %lld %lld\n",seg[i].x,seg[i].y,seg[i].ht,seg[i].v); puts("");
82     sort(seg+1,seg+n*2+1);
83 //    for(ll i=1;i<=n*2;++i) printf("%lld %lld %lld %lld\n",seg[i].x,seg[i].y,seg[i].ht,seg[i].v); puts("");
84     ll ans=0;
85     for(ll i=1;i<=n*2-1;++i) {
86         st.Modify(seg[i].x,seg[i].y,seg[i].v);
87         ans+=(seg[i+1].ht-seg[i].ht)*st.Query();
88 //        printf("%lld %lld %lld %lld\n",seg[i].x,seg[i].y,seg[i].ht,seg[i].v);
89 //        printf("%lld %lld %lld %lld\n",seg[i].ht,seg[i+1].ht,st.Query(),ans);
90 //        st.search(1,1,num-1);
91 //        puts("");
92     }
93     printf("%lld\n",ans);
94     return 0;
95 }