扫描线板子题。注意两倍数组(不太清楚原理) 一位大佬的博客:https://blog.csdn.net/qq_38786088/article/details/78633478,讲的太好了。 1 #includeiostream 2 #includealgorithm 3 #includecstdio 4 5 using namesp
扫描线板子题。注意两倍数组(不太清楚原理)
一位大佬的博客:https://blog.csdn.net/qq_38786088/article/details/78633478,讲的太好了。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 5 using namespace std; 6 typedef long long ll; 7 8 const int Maxn = 2e5+10; 9 10 ll read(){ 11 ll ans = 0;char last = ‘ ‘,ch = getchar(); 12 while(ch < ‘0‘||ch > ‘9‘)last = ch,ch = getchar(); 13 while(‘0‘ <= ch&&ch <= ‘9‘)ans = ans*10+ch-‘0‘,ch = getchar(); 14 if(last == ‘-‘)return -ans;return ans; 15 } 16 17 struct node{ 18 ll x,y1,y2,k; 19 bool operator <(const node& asdf)const{ 20 return x < asdf.x; 21 } 22 }rem[Maxn<<1]; 23 24 ll ans,n,tot1,tot2,cnt,x1,y1,x2,y2; 25 ll pos[Maxn<<1],a[Maxn<<1],cov[Maxn<<2],len[Maxn<<2]; 26 27 void pushup(ll p,ll s,int t){ 28 if(cov[p])len[p] = pos[t+1]-pos[s];//?? 29 else if(s == t)len[p] = 0; 30 else len[p] = len[p<<1]+len[p<<1|1]; 31 } 32 33 void update(ll L,ll R,ll s,ll t,ll p,ll k){ 34 if(L <= s&&t <= R){cov[p] += k;pushup(p,s,t);return;} 35 ll mid = s+t>>1; 36 if(L <= mid)update(L,R,s,mid,p<<1,k); 37 if(mid < R)update(L,R,mid+1,t,p<<1|1,k); 38 pushup(p,s,t); 39 } 40 41 int main(){ 42 n = read(); 43 for(int i = 1;i <= n;i++){ 44 x1 = read(),y1 = read(),x2 = read(),y2 = read(); 45 a[++tot1] = y1,a[++tot1] = y2; 46 rem[++tot2].x = x1,rem[tot2].y1 = y1,rem[tot2].y2 = y2,rem[tot2].k = 1; 47 rem[++tot2].x = x2,rem[tot2].y1 = y1,rem[tot2].y2 = y2,rem[tot2].k = -1; 48 } 49 sort(a+1,a+tot1+1); 50 for(int i = 1;i <= tot1;i++)if(a[i] != a[i-1]||i == 1)pos[++cnt] = a[i]; 51 sort(rem+1,rem+tot2+1); 52 for(int i = 1;i < tot2;i++){ 53 ll L = lower_bound(pos+1,pos+cnt+1,rem[i].y1)-pos; 54 ll R = lower_bound(pos+1,pos+cnt+1,rem[i].y2)-pos; 55 update(L,R-1,1,cnt,1,rem[i].k); 56 ans += len[1]*(rem[i+1].x-rem[i].x); 57 } 58 cout << ans; 59 return 0; 60 }