HDOJ 1828 线段树 矩形周长并
Posted Flowersea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ 1828 线段树 矩形周长并相关的知识,希望对你有一定的参考价值。
链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1828
代码:
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <queue> 5 #include <stack> 6 #include <cstdio> 7 #include <string> 8 #include <vector> 9 #include <cstdlib> 10 #include <cstring> 11 #include <sstream> 12 #include <iostream> 13 #include <algorithm> 14 #include <functional> 15 using namespace std; 16 #define rep(i,a,n) for (int i=a;i<n;i++) 17 #define per(i,a,n) for (int i=n-1;i>=a;i--) 18 #define all(x) (x).begin(),(x).end() 19 #define pb push_back 20 #define mp make_pair 21 #define lson l,m,rt<<1 22 #define rson m+1,r,rt<<1|1 23 typedef long long ll; 24 typedef vector<int> VI; 25 typedef pair<int, int> PII; 26 const ll MOD = 1e9 + 7; 27 const int INF = 0x3f3f3f3f; 28 const int MAXN = 2e4 + 7; 29 // head 30 31 int cnt[MAXN << 2]; 32 int sum[MAXN << 2], num[MAXN << 2]; 33 int lbd[MAXN << 2], rbd[MAXN << 2]; 34 35 struct seg { 36 int l, r, h, d; 37 const bool operator<(const seg &t) const { 38 return h < t.h; 39 } 40 }s[MAXN << 1]; 41 42 void pushup(int l, int r, int rt) { 43 if (cnt[rt]) { 44 lbd[rt] = rbd[rt] = 1; 45 sum[rt] = r - l + 1; 46 num[rt] = 2; 47 } 48 else if (l == r) lbd[rt] = rbd[rt] = sum[rt] = num[rt] = 0; 49 else { 50 lbd[rt] = lbd[rt << 1], rbd[rt] = rbd[(rt << 1) | 1]; 51 sum[rt] = sum[rt << 1] + sum[(rt << 1) | 1]; 52 num[rt] = num[rt << 1] + num[(rt << 1) | 1]; 53 if (rbd[rt << 1] && lbd[(rt << 1) | 1]) num[rt] -= 2; 54 } 55 } 56 57 void update(int L, int R, int d, int l, int r, int rt) { 58 if (L <= l && r <= R) { 59 cnt[rt] += d; 60 pushup(l, r, rt); 61 return; 62 } 63 int m = (l + r) >> 1; 64 if (L <= m) update(L, R, d, lson); 65 if (R > m) update(L, R, d, rson); 66 pushup(l, r, rt); 67 } 68 69 int main() { 70 int n; 71 while (cin >> n) { 72 int m = 0; 73 rep(i, 0, n) { 74 int x1, x2, y1, y2; 75 scanf("%d%d%d%d", &x1, &y1, &x2, &y2); 76 s[m++] = seg{ x1,x2,y1,1 }; 77 s[m++] = seg{ x1,x2,y2,-1 }; 78 } 79 sort(s, s + m); 80 int ans = 0, last = 0; 81 rep(i, 0, m) { 82 if (s[i].l < s[i].r) update(s[i].l, s[i].r - 1, s[i].d, -1e4, 1e4, 1); 83 ans += num[1] * (s[i + 1].h - s[i].h); 84 ans += abs(sum[1] - last); 85 last = sum[1]; 86 } 87 cout << ans << endl; 88 } 89 return 0; 90 }
以上是关于HDOJ 1828 线段树 矩形周长并的主要内容,如果未能解决你的问题,请参考以下文章
HDOJ1828&&POJ1177Picture(线段树,扫描线)