三篇线段树扫描线总结

来源:互联网 发布:帝国cms生成html 编辑:程序博客网 时间:2024/06/07 02:31

HDU 1542 Atlantis,裸面积并

<span style="font-size:24px;">#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int maxn = 200;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1struct seg{double l, r, h;int s;seg(){}seg(double a, double b, double c, int d) :l(a), r(b), h(c), s(d){}bool operator< (const seg& cmp) const{return h < cmp.h;}}node[maxn<<2];double sum[maxn << 2], X[maxn << 2];int cnt[maxn << 2];int bin(double a,int r){int l=0, m;while (l <= r){m = (l + r) >> 1;if (X[m] == a) return m;else if (X[m] < a) l = m + 1;else r = m - 1;}return -1;}void PushUp(int rt, int l, int r){if (cnt[rt]) sum[rt] = X[r + 1] - X[l];else if (l == r) sum[rt] = 0;else sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];}void update(int L, int R, int c, int l, int r, int rt){if (L <= l&&r <= R){cnt[rt] += c;PushUp(rt, l, r);return;}int m = (l + r) >> 1;if (L <= m) update(L, R, c, lson);if (R > m) update(L, R, c, rson);PushUp(rt, l, r);}int main(){int n,cas = 1;while (scanf("%d", &n) && n){int m = 0;for (int i = 0; i < n; i++){double a, b, c, d;scanf("%lf%lf%lf%lf", &a, &b, &c, &d);node[m] = seg(a, c, b, 1);X[m++] = a;node[m] = seg(a, c, d, -1);X[m++] = c;}int k = 1;sort(X, X + m);sort(node, node + m);for (int i = 1; i < m; i++)if (X[i] != X[i - 1])X[k++] = X[i];memset(cnt, 0, sizeof(cnt));memset(sum, 0, sizeof(sum));double ans = 0;for (int i = 0; i < m - 1; i++){int l = bin(node[i].l, k - 1);int r = bin(node[i].r, k - 1) - 1;if (l <= r)update(l, r, node[i].s, 0, k - 1, 1);ans += sum[1] * (node[i + 1].h - node[i].h);}printf("Test case #%d\nTotal explored area: %.2lf\n\n", cas++, ans);}return 0;}</span>



HDU 1828 Picture 裸周长并

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int maxn = 22222;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1bool lbd[maxn << 2], rbd[maxn << 2];int num[maxn << 2], len[maxn << 2], cnt[maxn << 2];struct Seg{int l, r, h, s;Seg(){}Seg(int a, int b, int c, int d) :l(a), r(b), h(c), s(d){}bool operator<(const Seg& cmp) const{if (h == cmp.h)return s>cmp.s;return h < cmp.h;}}seg[maxn];void PushUp(int rt, int l, int r){if (cnt[rt]){len[rt] = r - l + 1;num[rt] = 2;lbd[rt] = rbd[rt] = true;}else if (l == r){len[rt] = num[rt] = lbd[rt] = rbd[rt] = 0;}else{len[rt] = len[rt << 1] + len[rt << 1 | 1];num[rt] = num[rt << 1] + num[rt << 1 | 1];lbd[rt] = lbd[rt << 1];rbd[rt] = rbd[rt << 1 | 1];if (lbd[rt << 1 | 1] && rbd[rt << 1])num[rt] -= 2;}}void update(int L, int R, int c, int l, int r, int rt){if (L <= l&&r <= R){cnt[rt] += c;PushUp(rt, l, r);return;}int  m = (l + r) >> 1;if (L <= m) update(L, R, c, lson);if (R > m) update(L, R, c, rson);PushUp(rt, l, r);}int main(){int n;while (scanf("%d", &n) != EOF){int m = 0;int L = maxn, R = -maxn;for (int i = 0; i < n; i++){int a, b, c, d;scanf("%d%d%d%d", &a, &b, &c, &d);L = min(L, a);R = max(R, c);seg[m++] = Seg(a, c, b, 1);seg[m++] = Seg(a, c, d, -1);}sort(seg, seg + m);int ans = 0, last = 0;for (int i = 0; i < m; i++){update(seg[i].l, seg[i].r - 1, seg[i].s, L, R - 1, 1);ans += num[1] * (seg[i + 1].h - seg[i].h);ans += abs(len[1] - last);last = len[1];}printf("%d\n", ans);}return 0;}

HDU 1255 多重覆盖的面积求和

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1const int maxn = 2222;double x[maxn << 2], len[maxn << 2], len2[maxn << 2];int cnt[maxn << 2];struct Seg{double l, r, h;int s;Seg(){}Seg(double a, double b, double c, int d) :l(a), r(b), h(c), s(d){}bool operator<(const Seg& cmp){if (h == cmp.h)return s<cmp.s;return h < cmp.h;}}seg[maxn << 2];void init(){memset(cnt, 0, sizeof(cnt));memset(len, 0, sizeof(len));memset(len2, 0, sizeof(len2));}void PushUp(int rt, int l, int r){if (abs(cnt[rt]) >= 2){len2[rt] = len[rt] = x[r + 1] - x[l];}else if (abs(cnt[rt]) == 1){len2[rt] = x[r + 1] - x[l];len[rt] = len2[rt << 1] + len2[rt << 1 | 1];}else if (l == r){len[rt] = len2[rt] = 0;}else{len[rt] = len[rt << 1] + len[rt << 1 | 1];len2[rt] = len2[rt << 1] + len2[rt << 1 | 1];}}void update(int L, int R, int c, int l, int r, int rt){if (L <= l&&r <= R){cnt[rt] += c;PushUp(rt, l, r);return;}int m = (l + r) >> 1;if (L <= m) update(L, R, c, lson);if (R > m) update(L, R, c, rson);PushUp(rt, l, r);}int bin(double key, int r){int l = 0, m;while (l <= r){m = (l + r) >> 1;if (key == x[m]) return m;else if (key < x[m]) r = m - 1;else l = m + 1;}return -1;}int main(){int T;scanf("%d", &T);while (T--){int n, m = 0;scanf("%d", &n);for (int i = 0; i < n; i++){double a, b, c, d;scanf("%lf%lf%lf%lf", &a, &b, &c, &d);x[m] = a;seg[m++] = Seg(a, c, b, 1);x[m] = c;seg[m++] = Seg(a, c, d, -1);}sort(seg, seg + m);sort(x, x + m);int k = 1;for (int i = 1; i < m; i++)if (x[i] != x[i - 1])x[k++] = x[i];double ans = 0.0;for (int i = 0; i < m - 1; i++){int l = bin(seg[i].l, k - 1);int r = bin(seg[i].r, k - 1) - 1;if (l <= r)update(l, r, seg[i].s, 0, k - 1, 1);ans += len[1] * (seg[i + 1].h - seg[i].h);}printf("%.2lf\n", ans);init();}return 0;}


0 0
原创粉丝点击