HDU 3265 Posters (线段树+扫描线)(面积并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3265
给你n个中间被挖空了一个矩形的中空矩形,让你求他们的面积并。
其实一个中空矩形可以分成4个小的矩形,然后就是面积并,特别注意的是x1 == x3 || x2 == x4的时候,要特判一下,否则会RE。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 const int MAXN = 2e5 + 10; 7 typedef long long LL; 8 struct data { 9 LL l , r , y , flag; 10 bool operator <(const data& cmp) const { 11 return y < cmp.y; 12 } 13 }a[MAXN << 3]; 14 struct segtree { 15 LL val , l , r , add; 16 }T[MAXN << 3]; 17 18 void build(int p , int l , int r) { 19 int mid = (l + r) >> 1; 20 T[p].l = l , T[p].r = r , T[p].val = T[p].add = 0; 21 if(r - l == 1) { 22 return ; 23 } 24 build(p << 1 , l , mid); 25 build((p << 1)|1 , mid , r); 26 } 27 28 void pushup(int p) { 29 if(T[p].add) { 30 T[p].val = T[p].r - T[p].l; 31 } 32 else if(T[p].r - T[p].l == 1){ 33 T[p].val = 0; 34 } 35 else { 36 T[p].val = T[p << 1].val + T[(p << 1)|1].val; 37 } 38 } 39 40 void updata(int p , int l , int r , int add) { 41 int mid = (T[p].l + T[p].r) >> 1; 42 if(T[p].l == l && T[p].r == r) { 43 T[p].add += add; 44 pushup(p); 45 return ; 46 } 47 if(r <= mid) { 48 updata(p << 1 , l , r , add); 49 } 50 else if(l >= mid) { 51 updata((p << 1)|1 , l , r , add); 52 } 53 else { 54 updata(p << 1 , l , mid , add); 55 updata((p << 1)|1 , mid , r , add); 56 } 57 pushup(p); 58 } 59 60 int main() 61 { 62 int n; 63 LL x[8] , y[8]; 64 while(~scanf("%d" , &n) && n) { 65 int f = 0; 66 for(int i = 0 ; i < n ; i++) { 67 for(int j = 1 ; j <= 4 ; j++) { 68 scanf("%lld %lld" , x + j , y + j); 69 } 70 sort(x + 1 , x + 5); 71 sort(y + 1 , y + 5); 72 a[f].l = x[1] , a[f].r = x[4] , a[f].y = y[4] , a[f].flag = -1; 73 f++; 74 a[f].l = x[1] , a[f].r = x[4] , a[f].y = y[3] , a[f].flag = 1; 75 f++; 76 a[f].l = x[1] , a[f].r = x[4] , a[f].y = y[2] , a[f].flag = -1; 77 f++; 78 a[f].l = x[1] , a[f].r = x[4] , a[f].y = y[1] , a[f].flag = 1; 79 f++; 80 81 a[f].l = x[1] , a[f].r = x[2] , a[f].y = y[3] , a[f].flag = -1; 82 f++; 83 a[f].l = x[1] , a[f].r = x[2] , a[f].y = y[2] , a[f].flag = 1; 84 f++; 85 a[f].l = x[3] , a[f].r = x[4] , a[f].y = y[3] , a[f].flag = -1; 86 f++; 87 a[f].l = x[3] , a[f].r = x[4] , a[f].y = y[2] , a[f].flag = 1; 88 f++; 89 } 90 sort(a , a + f); 91 LL res = 0; 92 build(1 , 0 , 2e5 + 2); 93 //注意l == r的特殊情况 94 if(a[0].l != a[0].r) 95 updata(1 , a[0].l , a[0].r , a[0].flag); 96 for(int i = 1 ; i < f ; i++) { 97 res += (a[i].y - a[i - 1].y) * T[1].val; 98 if(a[i].r > a[i].l) 99 updata(1 , a[i].l , a[i].r , a[i].flag); 100 } 101 printf("%lld\n" , res); 102 } 103 }