poj 1177 & hdu 1828 Picture 线段树 扫描线求矩形周长并
题目链接:http://poj.org/problem?id=1177
题意:给出n个矩形,求周长并
思路:第一种方法和矩形面积并差不多。
先做一次对x坐标离散化,然后从下往上扫描,每扫描到一条线段,更新线段树,然后答案加上该次的整个区间被覆盖的长度与上次的差的绝对值。
再做一次对y坐标离散化,然后从左往右扫描,每扫描到一条线段,更新线段树,然后答案加上该次的整个区间被覆盖的长度与上次的差的绝对值。
poj上可以A,不知道为什么hdu上交G++是wa,交C++就A了。。。
1 //#include <bits/stdc++.h> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <string> 6 #include <algorithm> 7 #include <cmath> 8 #include <map> 9 using namespace std; 10 int n; 11 #define maxn 10010 12 #define lson l, m, rt<<1 13 #define rson m+1, r, rt<<1|1 14 struct Seg 15 { 16 int x1, y1, x2, y2; 17 }seg[maxn]; 18 struct Line 19 { 20 int l, r, h; 21 int mark; 22 }line[maxn]; 23 int a[maxn], b[maxn]; 24 map <int, int> mp; 25 int cnt; 26 int ans; 27 bool cmp(Line l1, Line l2) 28 { 29 return l1.h < l2.h; 30 } 31 int sum[(maxn*2)<<2]; 32 int cover[(maxn*2)<<2]; 33 void pushup(int l, int r, int rt) 34 { 35 if(sum[rt]) cover[rt] = mp[r+1] - mp[l]; 36 else 37 { 38 if(r == l) cover[rt] = 0; 39 else cover[rt] = cover[rt<<1] + cover[rt<<1|1]; 40 } 41 } 42 void build(int l, int r, int rt) 43 { 44 cover[rt] = 0; sum[rt] = 0; 45 if(l == r) return; 46 int m = (l+r)>>1; 47 build(lson); 48 build(rson); 49 pushup(l, r, rt); 50 } 51 void update(int L, int R, int val, int l, int r, int rt) 52 { 53 if(L == l && R == r) 54 { 55 sum[rt] += val; 56 pushup(l, r, rt); 57 return; 58 } 59 int m = (l+r)>>1; 60 if(R <= m) update(L, R, val, lson); 61 else if(L > m) update(L, R, val, rson); 62 else 63 { 64 update(L, m, val, lson); 65 update(m+1, R, val, rson); 66 } 67 pushup(l, r, rt); 68 } 69 void slovex() 70 { 71 cnt = 0; mp.clear(); 72 for(int i = 1; i <= n; i++) 73 { 74 a[cnt++] = seg[i].x1; a[cnt++] = seg[i].x2; 75 line[i*2-1].l = seg[i].x1; line[i*2-1].r = seg[i].x2; 76 line[i*2-1].h = seg[i].y1; line[i*2-1].mark = 1; 77 line[i*2].l = seg[i].x1; line[i*2].r = seg[i].x2; 78 line[i*2].h = seg[i].y2; line[i*2].mark = -1; 79 } 80 for(int i = 0; i < cnt; i++) b[i] = a[i]; 81 sort(a, a+cnt); 82 int precnt = cnt; 83 cnt = unique(a, a+cnt) - a; 84 for(int i = 0; i < precnt; i++) mp[lower_bound(a, a+cnt, b[i]) - a + 1] = b[i]; 85 sort(line+1, line+1+2*n, cmp); 86 build(1, cnt, 1); 87 int precover = 0; 88 for(int i = 1; i <= 2*n; i++) 89 { 90 int ll = lower_bound(a, a+cnt, line[i].l) - a + 1; 91 int rr = lower_bound(a, a+cnt, line[i].r) - a + 1; 92 update(ll, rr-1, line[i].mark, 1, cnt, 1); 93 ans += abs(precover - cover[1]); 94 precover = cover[1]; 95 } 96 } 97 void slovey() 98 { 99 cnt = 0; mp.clear(); 100 for(int i = 1; i <= n; i++) 101 { 102 a[cnt++] = seg[i].y1; a[cnt++] = seg[i].y2; 103 line[i*2-1].l = seg[i].y1; line[i*2-1].r = seg[i].y2; 104 line[i*2-1].h = seg[i].x1; line[i*2-1].mark = 1; 105 line[i*2].l = seg[i].y1; line[i*2].r = seg[i].y2; 106 line[i*2].h = seg[i].x2; line[i*2].mark = -1; 107 } 108 for(int i = 0; i < cnt; i++) b[i] = a[i]; 109 sort(a, a+cnt); 110 int precnt = cnt; 111 cnt = unique(a, a+cnt) - a; 112 for(int i = 0; i < precnt; i++) mp[lower_bound(a, a+cnt, b[i]) - a + 1] = b[i]; 113 sort(line+1, line+1+2*n, cmp); 114 build(1, cnt, 1); 115 int precover = 0; 116 for(int i = 1; i <= 2*n; i++) 117 { 118 int ll = lower_bound(a, a+cnt, line[i].l) - a + 1; 119 int rr = lower_bound(a, a+cnt, line[i].r) - a + 1; 120 update(ll, rr-1, line[i].mark, 1, cnt, 1); 121 ans += abs(precover - cover[1]); 122 precover = cover[1]; 123 } 124 } 125 int main() 126 { 127 //freopen("in.txt", "r", stdin); 128 //freopen("out.txt", "w", stdout); 129 int cast = 0; 130 while(~scanf("%d", &n)) 131 { 132 cnt = 0; mp.clear(); 133 for(int i = 1; i <= n; i++) scanf("%d%d%d%d", &seg[i].x1, &seg[i].y1, &seg[i].x2, &seg[i].y2); 134 ans = 0; 135 slovex(); slovey(); 136 printf("%d\n", ans); 137 } 138 return 0; 139 }