线段树 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
- 线段树 2017.4.26
- 线段树 2017.4.20
- string 26线段树
- 线段树?线段树!
- 线段树?线段树!
- 线段_线段树
- 线段_线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- web项目过滤器与拦截器小细节
- 剑指offer:和为S的两个数字
- Android开发线程间的交互之异步任务(AsyncTask)
- 设计模式学习之策略模式
- [bzoj4860]树的难题
- 线段树 2017.4.26
- web前端工程师--html和css基础课程(三)
- 第一章 布尔检索
- msg=SolrCore 'collection1' is not available due to init failure: Could not load conf for core collec
- ognl表达式要点
- Spring中配置和读取多个Properties文件--转
- 编译在linux arm核上运行的内核模块
- 用Markdown写表格
- android学习线路