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 }

 

posted @ 2016-04-27 23:26  Recoder  阅读(167)  评论(0编辑  收藏  举报