Codeforces Round #337 (Div. 2) D. Vika and Segments (线段树+扫描线+离散化)
题目链接:http://codeforces.com/contest/610/problem/D
就是给你宽度为1的n个线段,然你求总共有多少单位的长度。
相当于用线段树求面积并,只不过宽为1,注意y和x的最大都要+1,这样才相当于求面积。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <map> 5 #include <algorithm> 6 using namespace std; 7 const int MAXN = 4e5 + 5; 8 typedef __int64 LL; 9 struct data { 10 LL x1 , x2 , y , flag; 11 bool operator <(const data& cmp) const { 12 return y < cmp.y; 13 } 14 }a[MAXN]; 15 struct segtree { 16 LL l , r , lazy , val; 17 }T[MAXN << 2]; 18 map <LL , LL> mp; 19 LL x[MAXN]; 20 21 void build(int p , int l , int r) { 22 int mid = (l + r) >> 1; 23 T[p].l = l , T[p].r = r , T[p].val = T[p].lazy = 0; 24 if(r - l == 1) { 25 return ; 26 } 27 build(p << 1 , l , mid); 28 build((p << 1)|1 , mid , r); 29 } 30 31 void pushup(int p) { 32 if(T[p].lazy) { 33 T[p].val = (x[T[p].r] - x[T[p].l]); 34 } 35 else if(T[p].r - T[p].l == 1) { 36 T[p].val = 0; 37 } 38 else { 39 T[p].val = T[p << 1].val + T[(p << 1)|1].val; 40 } 41 } 42 43 void updata(int p , int l , int r , int val) { 44 int mid = (T[p].l + T[p].r) >> 1; 45 if(T[p].l == l && T[p].r == r) { 46 T[p].lazy += val; 47 pushup(p); 48 return ; 49 } 50 if(r <= mid) { 51 updata(p << 1 , l , r , val); 52 } 53 else if(l >= mid) { 54 updata((p << 1)|1 , l , r , val); 55 } 56 else { 57 updata(p << 1 , l , mid , val); 58 updata((p << 1)|1 , mid , r , val); 59 } 60 pushup(p); 61 } 62 63 int main() 64 { 65 int n , f = 0 , cnt = 0; 66 LL x1 , x2 , y1 , y2; 67 scanf("%d" , &n); 68 for(int i = 0 ; i < n ; i++) { 69 scanf("%I64d %I64d %I64d %I64d" , &x1 , &y1 , &x2 , &y2); 70 if(x1 > x2) 71 swap(x1 , x2); 72 x2++; 73 if(y1 > y2) 74 swap(y1 , y2); 75 y2++; 76 a[f].x1 = x1 , a[f].x2 = x2 , a[f].y = y1 , a[f].flag = 1; 77 f++; 78 a[f].x1 = x1 , a[f].x2 = x2 , a[f].y = y2 , a[f].flag = -1; 79 f++; 80 if(!mp[x1]) { 81 mp[x1] = 1; 82 x[++cnt] = x1; 83 } 84 if(!mp[x2]) { 85 mp[x2] = 1; 86 x[++cnt] = x2; 87 } 88 } 89 build(1 , 1 , cnt); 90 sort(a , a + f); 91 sort(x + 1 , x + cnt + 1); 92 for(int i = 0 ; i < f ; i++) { 93 int pos = lower_bound(x + 1 , x + cnt + 1 , a[i].x1) - x; 94 a[i].x1 = pos; 95 pos = lower_bound(x + 1 , x + cnt + 1 , a[i].x2) - x; 96 a[i].x2 = pos; 97 } 98 LL res = 0; 99 updata(1 , a[0].x1 , a[0].x2 , a[0].flag); 100 for(int i = 1 ; i < f ; i++) { 101 res += (LL)(a[i].y - a[i - 1].y) * T[1].val; 102 updata(1 , a[i].x1 , a[i].x2 , a[i].flag); 103 } 104 printf("%I64d\n" , res); 105 }