线段树 2017.4.26

来源:互联网 发布:天纵软件 编辑:程序博客网 时间:2024/06/05 16:09

1、BZOJ 4364 [IOI2014]wall砖墙

解题思路:

维护区间最大值和最小值以及区间是否相同

加读入优化和不加读入优化


#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <set>#include <cmath>#include <cctype>#include <ctime>using namespace std;#define lc id << 1#define rc id << 1 | 1#define lson low, mid, lc#define rson mid + 1, high, rc#define REP(i, n) for (int i = 0; i < (n); ++i)#define eps 1e-9typedef long long ll;const int INF = 0x7fffffff;const int maxn = 2e6 + 10;const int maxk = 5e5 + 10;int n, k, op, Left, Right, height;int Max[maxn * 4], Min[maxn * 4], lazy[maxn * 4];inline int read(void) {    int ret = 0; char c = getchar();    while (c > '9' || c < '0') { c = getchar(); }    while ('0' <= c && c <= '9') { ret = ret * 10 + c - '0'; c = getchar(); }    return ret;}inline void push_up(int id) { Max[id] = max(Max[lc], Max[rc]); Min[id] = min(Min[lc], Min[rc]); }void build(int low, int high, int id) {    if (low == high) { Max[id] = 0; Min[id] = 0; lazy[id] = 0; return; }    int mid = (low + high) / 2; build(lson); build(rson);}inline void push_down(int id) {    if (lazy[id] == -1) { return; }    Max[lc] = lazy[id]; Min[lc] = lazy[id]; lazy[lc] = lazy[id];    Max[rc] = lazy[id]; Min[rc] = lazy[id]; lazy[rc] = lazy[id];    lazy[id] = -1;}void update1(int l, int r, int h, int low, int high, int id) {    if (l == low && r == high) {        if (h >= Max[id]) { Max[id] = h; Min[id] = h; lazy[id] = h; return; }        if (h <= Min[id]) { return; }    }    int mid = (low + high) / 2; push_down(id);    if (r <= mid) { update1(l, r, h, lson); }    else if (l >= mid + 1) { update1(l, r, h, rson); }    else { update1(l, mid, h, lson); update1(mid + 1, r, h, rson); }    push_up(id);}void update2(int l, int r, int h, int low, int high, int id) {    if (low == l && high == r) {        if (h <= Min[id]) { Max[id] = h; Min[id] = h; lazy[id] = h; return; }        if (h >= Max[id]) { return; }    }    int mid = (low + high) / 2; push_down(id);    if (r <= mid) { update2(l, r, h, lson); }    else if (l >= mid + 1) { update2(l, r, h, rson); }    else { update2(l, mid, h, lson); update2(mid + 1, r, h, rson); }    push_up(id);}void query(int low, int high, int id) {    if (lazy[id] != -1) { for (int i = low; i <= high; ++i) { printf("%d\n", Max[id]); } return; }    if (low == high) { printf("%d\n", Max[id]); return; }    int mid = (low + high) / 2; push_down(id); query(lson); query(rson);}int main() {#ifdef __AiR_H    freopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);#endif // __AiR_H    n = read(); k = read(); memset(lazy, -1, sizeof(lazy));    for (int i = 0; i < k; ++i) {        op = read(); Left = read(); Right = read(); height = read(); ++Left; ++Right;        if (op == 1) { update1(Left, Right, height, 1, n, 1); }        else { update2(Left, Right, height, 1, n, 1); }    }    query(1, n, 1);#ifdef __AiR_H    printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);#endif // __AiR_H    return 0;}


2、HZAU 1207 Candies

题目:acm.hzau.edu.cn/5th.pdf

参考:http://www.cnblogs.com/jianrenfang/p/6754620.html

PS:第一道线段树区间合并,开始在查询的时候直接把两个询问结果相加了。。。然后找不出错误wa到死。。。

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <set>#include <cmath>#include <cctype>#include <ctime>#include <cassert>using namespace std;#define REP(i, n) for (int i = 0; i < (n); ++i)#define eps 1e-9#define lc id << 1#define rc id << 1 | 1#define lson low, mid, lc#define rson mid + 1, high, rctypedef long long ll;typedef pair<int, int> pii;struct Node { int id, B, lb, rb, len; };const int INF = 0x7fffffff;const int maxn = 1e6 + 10;int T, n, m, cmd, L, R, v;char str[maxn];int num[maxn], lazy[maxn * 4], B[maxn * 4], lb[maxn * 4], rb[maxn * 4];inline void push_up(int id, int low, int mid, int high) {    if (lazy[lc] == 1 && lazy[rc] == 1) { lazy[id] = 1; B[id] = 0; lb[id] = 0; rb[id] = 0; return; }    if (lazy[lc] == 2 && lazy[rc] == 2) { lazy[id] = 2; B[id] = B[lc] + B[rc]; lb[id] = B[id]; rb[id] = B[id]; return; }    B[id] = max(rb[lc] + lb[rc], max(B[lc], B[rc])); lazy[id] = 0;    lb[id] = lb[lc]; if (lb[lc] == mid - low + 1) { lb[id] += lb[rc]; }    rb[id] = rb[rc]; if (rb[rc] == high - mid) { rb[id] += rb[lc]; }}void build(int low, int high, int id) {    if (low == high) {        if (num[low] == 2) { B[id] = 1; lazy[id] = 2; lb[id] = 1; rb[id] = 1; }        else { B[id] = 0; lazy[id] = 1; lb[id] = 0; rb[id] = 0; } return;    }    int mid = (low + high) / 2; build(lson); build(rson); push_up(id, low, mid, high);}inline void push_down(int id, int low, int mid, int high) {    if (lazy[id] == 0) { return; }    if (lazy[id] == 1) {        B[lc] = 0; B[rc] = 0; lazy[lc] = 1; lazy[rc] = 1; lazy[id] = 0;        lb[rc] = 0; lb[lc] = 0; rb[lc] = 0; rb[rc] = 0;        return;    }    B[lc] = mid - low + 1; B[rc] = high - mid; lazy[lc] = 2; lazy[rc] = 2; lazy[id] = 0;    lb[lc] = B[lc]; rb[lc] = B[lc]; lb[rc] = B[rc]; rb[rc] = B[rc];}void update(int l, int r, int key, int low, int high, int id) {    if (l == low && r == high) {        if (key == 1) { B[id] = 0; lazy[id] = 1; lb[id] = 0; rb[id] = 0; }        else { B[id] = high - low + 1; lazy[id] = 2; lb[id] = B[id]; rb[id] = B[id]; } return;    }    int mid = (low + high) / 2; push_down(id, low, mid, high);    if (r <= mid) { update(l, r, key, lson); }    else if (l >= mid + 1) { update(l, r, key, rson); }    else { update(l, mid, key, lson); update(mid + 1, r, key, rson); }    push_up(id, low, mid, high);}inline Node merge(Node l, Node r) {    Node ret; ret.len = l.len + r.len; ret.lb = l.lb; ret.rb = r.rb;    if (l.lb == l.len) { ret.lb += r.lb; }    if (r.rb == r.len) { ret.rb += l.rb; }    ret.B = max(l.rb + r.lb, max(l.B, r.B));    return ret;}Node query(int l, int r, int low, int high, int id) {    if (l == low && r == high) { return Node{id, B[id], lb[id], rb[id], r - l + 1}; }    int mid = (low + high) / 2; push_down(id, low, mid, high);    if (r <= mid) { return query(l, r, lson); }    else if (l >= mid + 1) { return query(l, r, rson); }    Node t1 = query(l, mid, lson), t2 = query(mid + 1, r, rson);    return merge(t1, t2);}int main() {#ifdef __AiR_H    freopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);#endif // __AiR_H    scanf("%d", &T); int Case = 0;    while (T--) {        printf("Case #%d:\n", ++Case);        scanf("%d %d", &n, &m);        scanf("%s", str); REP(i, n) { if (str[i] == 'A') { num[i + 1] = 1; } else { num[i + 1] = 2; } }        build(1, n, 1);        while (m--) {            scanf("%d %d %d", &cmd, &L, &R); if (cmd == 1) { scanf("%d", &v); }            if (cmd == 1) { update(L, R, v, 1, n, 1); }            else { printf("%d\n", query(L, R, 1, n, 1).B); }        }    }#ifdef __AiR_H    printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);#endif // __AiR_H    return 0;}


3、POJ 1177 Picture

题意:

求矩形并的周长

PS:第一道扫描线,好开心啊。。。

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <set>#include <cmath>#include <cctype>#include <ctime>#include <cassert>using namespace std;#define REP(i, n) for (int i = 0; i < (n); ++i)#define eps 1e-9#define PI acos(-1.0)#define lc id << 1#define rc id << 1 | 1#define lson low, mid, lc#define rson mid + 1, high, rctypedef long long ll;typedef pair<int, int> pii;struct Node {    int x, y1, y2, flag;    bool operator < (const Node& a) const {        if (x == a.x) { return flag > a.flag; } return x < a.x;    }};const int INF = 0x7fffffff;const int maxn = 1e4 + 10;vector<int> y;int n, a, b, c, d, ans = 0, len_t = 0, line_t = 0, id1, id2;Node node[maxn];int cnt[maxn * 4], line[maxn * 4], lbc[maxn * 4], rbc[maxn * 4], len[maxn * 4];int id(int x) { return lower_bound(y.begin(), y.end(), x) - y.begin() + 1; }inline void push_up(int id, int low, int high) {    if (cnt[id]) { len[id] = y[high] - y[low - 1]; line[id] = lbc[id] = rbc[id] = 1; return; }    len[id] = len[lc] + len[rc]; lbc[id] = lbc[lc]; rbc[id] = rbc[rc];    line[id] = line[lc] + line[rc] - rbc[lc] * lbc[rc];}void update(int l, int r, int key, int low, int high, int id) {    if (l == low && r == high) {        if (key) { ++cnt[id]; } else { --cnt[id]; }        if (low == high && cnt[id] == 0) { len[id] = line[id] = lbc[id] = rbc[id] = 0; return; }        push_up(id, low, high); return;    }    int mid = (low + high) / 2;    if (r <= mid) { update(l, r, key, lson); }    else if (l >= mid + 1) { update(l, r, key, rson); }    else { update(l, mid, key, lson); update(mid + 1, r, key, rson); }    push_up(id, low, high);}int main() {#ifdef __AiR_H    freopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);#endif // __AiR_H    scanf("%d", &n);    REP(i, n) {        scanf("%d %d %d %d", &a, &b, &c, &d); y.push_back(b); y.push_back(d);        node[i * 2] = Node{a, b, d, 1}; node[i * 2 + 1] = Node{c, b, d, 0};    }    sort(y.begin(), y.end()); y.erase(unique(y.begin(), y.end()), y.end());    n *= 2; sort(node, node + n); int Size = y.size() - 1;    REP(i, n) {        id1 = id(node[i].y1); id2 = id(node[i].y2);        update(id1, id2 - 1, node[i].flag, 1, Size, 1);        if (i > 0) { ans += 2 * line_t * (node[i].x - node[i - 1].x); }        ans += abs(len[1] - len_t); len_t = len[1]; line_t = line[1];    }    printf("%d\n", ans);#ifdef __AiR_H    printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);#endif // __AiR_H    return 0;}

4、POJ 1151 Atlantis

题意:

求矩形并的面积,比求周长要简单。。。而且这道题数据范围很小。。。

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <set>#include <cmath>#include <cctype>#include <ctime>#include <cassert>using namespace std;#define REP(i, n) for (int i = 0; i < (n); ++i)#define eps 1e-9#define PI acos(-1.0)#define lc id << 1#define rc id << 1 | 1#define lson low, mid, lc#define rson mid + 1, high, rctypedef long long ll;typedef pair<int, int> pii;struct Node {    double x, y1, y2; int flag;    bool operator < (const Node& a) const {        if (x == a.x) { return flag > a.flag; } return x < a.x;    }};const int INF = 0x7fffffff;const int maxn = 200 + 10;vector<double> y;int n, id1, id2, Size, Case = 0;double a, b, c, d, ans, len_t;Node node[maxn];int cnt[maxn * 4];double len[maxn * 4];int id(double x) { return lower_bound(y.begin(), y.end(), x) - y.begin() + 1; }void build(int low, int high, int id) {    cnt[id] = 0; len[id] = 0.0; if (low == high) { return; }    int mid = (low + high) / 2; build(lson); build(rson);}inline void push_up(int id, int low, int high) {    if (cnt[id]) { len[id] = y[high] - y[low - 1]; return; }    len[id] = len[lc] + len[rc];}void update(int l, int r, int key, int low, int high, int id) {    if (l == low && r == high) {        if (key) { ++cnt[id]; } else { --cnt[id]; }        if (low == high && cnt[id] == 0) { len[id] = 0.0; return; }        push_up(id, low, high); return;    }    int mid = (low + high) / 2;    if (r <= mid) { update(l, r, key, lson); }    else if (l >= mid + 1) { update(l, r, key, rson); }    else { update(l, mid, key, lson); update(mid + 1, r, key, rson); }    push_up(id, low, high);}int main() {#ifdef __AiR_H    freopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);#endif // __AiR_H    while (scanf("%d", &n) && n != 0) {        y.clear();        REP(i, n) {            scanf("%lf %lf %lf %lf", &a, &b, &c, &d); y.push_back(b); y.push_back(d);            node[i * 2] = Node{a, b, d, 1}; node[i * 2 + 1] = Node{c, b, d, 0};        }        sort(y.begin(), y.end()); y.erase(unique(y.begin(), y.end()), y.end());        n *= 2; sort(node, node + n); Size = y.size() - 1; build(1, Size, 1); ans = len_t = 0.0;        REP(i, n) {            id1 = id(node[i].y1); id2 = id(node[i].y2);            update(id1, id2 - 1, node[i].flag, 1, Size, 1);            if (i > 0) { ans += len_t * (node[i].x - node[i - 1].x); } len_t = len[1];        }        printf("Test case #%d\nTotal explored area: %.2f\n\n", ++Case, ans);    }#ifdef __AiR_H    printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);#endif // __AiR_H    return 0;}

5、POJ 2760 End of Windless Days

参考:http://www.cppblog.com/menjitianya/archive/2011/04/03/143336.html

PS:谨防RE

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <set>#include <cmath>#include <cctype>#include <ctime>#include <cassert>using namespace std;#define REP(i, n) for (int i = 0; i < (n); ++i)#define eps 1e-6#define PI acos(-1.0)#define lc id << 1#define rc id << 1 | 1#define lson low, mid, lc#define rson mid + 1, high, rctypedef long long ll;typedef pair<int, int> pii;struct Node {    double x, y1, y2; int flag;    bool operator < (const Node& a) const {        if (x == a.x) { return flag > a.flag; } return x < a.x;    }};const int INF = 0x7fffffff;const int maxn = 1e3 + 10;vector<double> y;int n, id1, id2, Size, N = 0;double a, b, c, d, e, a_t, b_t, c_t, d_t, ans, len_t, min_x, min_y, max_x, max_y, l_x, l_y, l_h;Node node[maxn];int cnt[maxn * 4];double len[maxn * 4];int id(double x) { return lower_bound(y.begin(), y.end(), x) - y.begin() + 1; }void build(int low, int high, int id) {    cnt[id] = 0; len[id] = 0.0; if (low == high) { return; }    int mid = (low + high) / 2; build(lson); build(rson);}inline void push_up(int id, int low, int high) {    if (cnt[id]) { len[id] = y[high] - y[low - 1]; return; }    len[id] = len[lc] + len[rc];}void update(int l, int r, int key, int low, int high, int id) {    if (l == low && r == high) {        if (key) { ++cnt[id]; } else { --cnt[id]; }        if (low == high && cnt[id] == 0) { len[id] = 0.0; return; }        push_up(id, low, high); return;    }    int mid = (low + high) / 2;    if (r <= mid) { update(l, r, key, lson); }    else if (l >= mid + 1) { update(l, r, key, rson); }    else { update(l, mid, key, lson); update(mid + 1, r, key, rson); }    push_up(id, low, high);}inline double cal(double a, double h1, double b, double h2) { return b - h2 * (b - a) / (h2 - h1); }int main() {#ifdef __AiR_H    freopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);#endif // __AiR_H    while (scanf("%d", &n) != EOF) {        scanf("%lf %lf %lf %lf %lf %lf %lf", &min_x, &min_y, &max_x, &max_y, &l_x, &l_y, &l_h);        y.clear(); N = 0;        REP(i, n) {            scanf("%lf %lf %lf %lf %lf", &a, &b, &c, &d, &e); if (fabs(l_h - e) < eps) { continue; }            if (a > c) { swap(a, c); } if (b > d) { swap(b, d); }            a_t = max(min_x, cal(a, e, l_x, l_h)); c_t = min(max_x, cal(c, e, l_x, l_h));            b_t = max(min_y, cal(b, e, l_y, l_h)); d_t = min(max_y, cal(d, e, l_y, l_h));            if (fabs(a_t - c_t) < eps || fabs(b_t - d_t) < eps || a_t > c_t || b_t > d_t) { continue; }            y.push_back(b_t); y.push_back(d_t);            node[N++] = Node{a_t, b_t, d_t, 1}; node[N++] = Node{c_t, b_t, d_t, 0};        }        sort(y.begin(), y.end()); y.erase(unique(y.begin(), y.end()), y.end());        sort(node, node + N); Size = y.size() - 1; ans = (max_x - min_x) * (max_y - min_y);        if (Size < 1) { printf("%.4f\n", ans); continue; }        build(1, Size, 1); len_t = 0.0;        REP(i, N) {            id1 = id(node[i].y1); id2 = id(node[i].y2);            update(id1, id2 - 1, node[i].flag, 1, Size, 1);            if (i > 0) { ans -= len_t * (node[i].x - node[i - 1].x); } len_t = len[1];        }        printf("%.4f\n", ans);    }#ifdef __AiR_H    printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);#endif // __AiR_H    return 0;}

0 0