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(线段树,扫描线)

51nod 1206 && hdu 1828 Picture (扫描线+离散化+线段树 矩阵周长并)

hdu1828 Picture (线段树:扫描线周长)

hdu1828线段树(两次扫描+离散化)

hdu1828(矩形周长并)

HDU 1828 Picture(线段树扫描线求周长)