标签:inpu long 单位 cal blank and which logs ada
题目链接:https://vjudge.net/problem/POJ-1177
Input
Output
Sample Input
7 -15 0 5 10 -5 8 20 25 15 -4 24 14 0 -6 16 4 2 15 10 22 30 10 36 20 34 0 40 16
Sample Output
228
题解:
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 using namespace std; 13 typedef long long LL; 14 const double EPS = 1e-8; 15 const int INF = 2e9; 16 const LL LNF = 2e18; 17 const int MAXN = 1e4+10; 18 19 struct line 20 { 21 int le, ri, h; 22 int id; 23 bool operator<(const line &a)const{ 24 return h<a.h; 25 } 26 }Line[MAXN]; 27 28 //X用于离散化横坐标,times为此区间被覆盖的次数,block为有多少块子区间, len为被覆盖的长度 29 int X[MAXN<<1], times[MAXN<<2], block[MAXN<<2], len[MAXN]; 30 bool usedl[MAXN<<2], usedr[MAXN<<2]; 31 //usedl用于表示区间的左端是否被覆盖, usedr亦如此 32 33 void push_up(int u, int l, int r) 34 { 35 if(times[u]>0) //该区间有被覆盖 36 { 37 len[u] = X[r] - X[l]; 38 block[u] = 1; 39 usedl[u] = usedr[u] = true; 40 } 41 else //该区间没有被覆盖 42 { 43 if(l+1==r) //该区间为单位区间 44 { 45 len[u] = 0; 46 block[u] = 0; 47 usedl[u] = usedr[u] = false; 48 } 49 else //该区间至少包含两个单位区间 50 { 51 len[u] = len[u*2] + len[u*2+1]; 52 block[u] = block[u*2] + block[u*2+1]; 53 if(usedr[u*2] && usedl[u*2+1]) //如果左半区间的右端与右半区间的左端均被覆盖,则他们合成一个子区间 54 block[u]--; 55 usedl[u] = usedl[u*2]; 56 usedr[u] = usedr[u*2+1]; 57 } 58 } 59 } 60 61 void add(int u, int l, int r, int x, int y, int v) 62 { 63 if(x<=l && r<=y) 64 { 65 times[u] += v; 66 push_up(u, l, r); 67 return; 68 } 69 70 int mid = (l+r)>>1; 71 if(x<=mid-1) add(u*2, l, mid, x, y, v); 72 if(y>=mid+1) add(u*2+1, mid, r, x, y, v); 73 push_up(u, l, r); 74 } 75 76 int main() 77 { 78 int n; 79 while(scanf("%d", &n)!=EOF) 80 { 81 for(int i = 1; i<=n; i++) 82 { 83 int x1, y1, x2, y2; 84 scanf("%d%d%d%d", &x1, &y1, &x2, &y2); 85 Line[i].le = Line[i+n].le = x1; 86 Line[i].ri = Line[i+n].ri = x2; 87 Line[i].h = y1; Line[i+n].h = y2; 88 Line[i].id = 1; Line[i+n].id = -1; 89 X[i] = x1; X[i+n] = x2; 90 } 91 92 sort(Line+1, Line+1+2*n); 93 sort(X+1, X+1+2*n); 94 int m = unique(X+1, X+1+2*n) - (X+1); 95 96 memset(times, 0, sizeof(times)); 97 memset(len, 0, sizeof(len)); 98 memset(block, 0, sizeof(block)); 99 memset(usedl, false, sizeof(usedl)); 100 memset(usedr, false, sizeof(usedr)); 101 102 int ans = 0, pre_len = 0; 103 Line[2*n+1].h = Line[2*n].h; //边界条件 104 for(int i = 1; i<=2*n; i++) 105 { 106 int l = upper_bound(X+1, X+1+m, Line[i].le) - (X+1); 107 int r = upper_bound(X+1, X+1+m, Line[i].ri) - (X+1); 108 add(1, 1, m, l, r, Line[i].id); 109 ans += abs(len[1] - pre_len); 110 ans += 2*block[1]*(Line[i+1].h-Line[i].h); 111 pre_len = len[1]; 112 } 113 114 printf("%d\n", ans); 115 } 116 }
POJ1177 Picture —— 求矩形并的周长 线段树 + 扫描线 + 离散化
标签:inpu long 单位 cal blank and which logs ada
原文地址:http://www.cnblogs.com/DOLFAMINGO/p/7748018.html