题目链接:
http://codeforces.com/problemset/problem/610/D
------------------------------------------------------------------------------------
虽然说这题是线段并 但是如果会写矩形面积并的话就直接写矩形并不用考虑那么多了
不过这里额外说明下 写矩形面积并的线段树的时候
要注意到某一段 $ -1 $一定是在这一段$ +1 $之后才会出现的操作
因此标记就是这一段被“完全”覆盖的次数 并且部分修改时无需进行标记下放
这题作为矩形面积并的第一道题也是很适合的
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 const int N = 1e5 + 10; 7 struct rec 8 { 9 int xa, ya, xb, yb; 10 }a[N]; 11 struct line 12 { 13 int x, ya, yb, num; 14 }b[N << 1]; 15 int hash[N << 1]; 16 int sum[N << 3], flag[N << 3]; 17 int n; 18 long long ans = 0; 19 bool cmp (const line &aa, const line &bb) 20 { 21 return aa.x < bb.x; 22 } 23 void pushup(int x, int tl, int tr) 24 { 25 if(flag[x]) 26 sum[x] = hash[tr + 1] - hash[tl]; 27 else if(tl != tr) 28 sum[x] = sum[x << 1] + sum[x << 1 | 1]; 29 else 30 sum[x] = 0; 31 return; 32 } 33 void update(int x, int L, int R, int tl, int tr, int num) 34 { 35 if(L <= tl && R >= tr) 36 { 37 flag[x] += num; 38 pushup(x, tl, tr); 39 return; 40 } 41 int mid = (tl + tr) >> 1; 42 if(L <= mid) 43 update(x << 1, L, R, tl, mid, num); 44 if(R > mid) 45 update(x << 1 | 1, L, R, mid + 1, tr, num); 46 pushup(x, tl, tr); 47 } 48 int main() 49 { 50 scanf("%d", &n); 51 for(int i = 1; i <= n; ++i) 52 { 53 scanf("%d%d%d%d", &a[i].xa, &a[i].ya, &a[i].xb, &a[i].yb); 54 if(a[i].xa > a[i].xb) 55 swap(a[i].xa, a[i].xb); 56 if(a[i].ya > a[i]. yb) 57 swap(a[i].ya, a[i].yb); 58 ++a[i].xb; 59 ++a[i].yb; 60 hash[i * 2 - 1] = a[i].ya; 61 hash[i * 2] = a[i].yb; 62 b[i * 2 - 1].x = a[i].xa; 63 b[i * 2 - 1].num = 1; 64 b[i * 2].x = a[i].xb; 65 b[i * 2].num = -1; 66 b[i * 2].ya = b[i * 2 - 1].ya = a[i].ya; 67 b[i * 2].yb = b[i * 2 - 1].yb = a[i].yb; 68 } 69 sort(hash + 1, hash + 1 + n * 2); 70 sort(b + 1, b + 1 + n * 2, cmp); 71 b[0].x = b[1].x; 72 for(int i = 1; i <= n * 2; ++i) 73 { 74 int L, R; 75 L = lower_bound(hash + 1, hash + 1 + n * 2, b[i].ya) - hash; 76 R = lower_bound(hash + 1, hash + 1 + n * 2, b[i].yb) - hash - 1; 77 ans += (long long) (b[i].x - b[i - 1].x) * sum[1]; 78 update(1, L, R, 1, n * 2 - 1, b[i].num); 79 } 80 printf("%lld\n", ans); 81 return 0; 82 }
CodeForces 610D Vika and Segments
原文:http://www.cnblogs.com/sagitta/p/5164698.html