ZOJ 3299 Fall the Brick(线段树区间更新)
2015-08-01 14:33
453 查看
题意:
有n块板砖从天而降,底下有了m块木板来挡,每块板砖长度为1单位。现在题目给出连续板砖的范围还有木板的范围与高度,问最后每块木板上有几块板砖。
解析:
这题想了挺久的最后终于搞定了。线段树的区间更新问题。
由于lil_i和rir_i比较大(0<=li<ri<=30000000)(0 <= l_i < r_i <= 30000000),首先考虑到的是对左右边界进行离散化。然后先按照木板从低到高进行排序,然后对区间进行染色。
然后再把所有的砖块放上去,对区间进行更新,维护一个addv的懒惰标记,代表这个区间被覆盖了多少层。
最后进行到一次直到叶子节点的总查询得到最终答案。
总复杂度O((n+m+tot)log2n)O((n+m+tot)log_2n)
注意:
这题对内存的要求比较高,开小了会re,开大了会mle。mymy codecode
[code]#pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <cstring> #include <algorithm> #define ls (o<<1) #define rs (o<<1|1) #define lson ls, L, M #define rson rs, M+1, R using namespace std; typedef long long ll; const int N = 100005; struct Node { int ll, rr, lid, rid; int h, id; } brick , board ; int n, m, tot; int id[N*6]; ll length[N*6], ans ; bool cmp(Node a, Node b) { return a.h < b.h; } void discrete() { sort(id, id+tot); tot = unique(id, id+tot) - id; for(int i = 1; i <= n; i++) { brick[i].lid = lower_bound(id, id+tot, brick[i].ll) - id; brick[i].rid = lower_bound(id, id+tot, brick[i].rr) - id - 1; } for(int i = 1; i <= m; i++) { board[i].lid = lower_bound(id, id+tot, board[i].ll) - id; board[i].rid = lower_bound(id, id+tot, board[i].rr) - id - 1; } for(int i = 0; i < tot-1; i++) { length[i] = id[i+1] - id[i]; } } ll color[N*12], addv[N*12]; void build(int o, int L, int R) { color[o] = addv[o] = 0; if(L == R) return ; int M = (L + R)/2; build(lson); build(rson); } void pushDown(int o) { if(color[o]) { color[ls] = color[rs] = color[o]; color[o] = 0; } if(addv[o]) { addv[ls] += addv[o]; addv[rs] += addv[o]; addv[o] = 0; } } void setColor(int o, int L, int R, int ql, int qr, int val) { if(ql <= L && R <= qr) { color[o] = val; return ; } pushDown(o); int M = (L + R)/2; if(ql <= M) setColor(lson, ql, qr, val); if(qr > M) setColor(rson, ql, qr, val); } void modify(int o, int L, int R, int ql, int qr) { if(ql <= L && R <= qr) { addv[o]++; return ; } pushDown(o); int M = (L + R)/2; if(ql <= M) modify(lson, ql, qr); if(qr > M) modify(rson, ql, qr); } void query(int o, int L, int R) { if(L == R) { if(color[o]) ans[color[o]] += addv[o]*length[L]; return ; } pushDown(o); int M = (L + R)/2; query(lson); query(rson); } int main() { while(scanf("%d%d", &n, &m) != EOF) { tot = 0; for(int i = 1; i <= n; i++) { scanf("%d%d", &brick[i].ll, &brick[i].rr); id[tot++] = brick[i].ll; id[tot++] = brick[i].rr; } for(int i = 1; i <= m; i++) { scanf("%d%d%d", &board[i].ll, &board[i].rr, &board[i].h); id[tot++] = board[i].ll; id[tot++] = board[i].rr; board[i].id = i; } discrete(); int end = tot-2; build(1, 0, end); sort(board+1, board+m+1, cmp); for(int i = 1; i <= m; i++) setColor(1, 0, end, board[i].lid, board[i].rid, board[i].id); for(int i = 1; i <= n; i++) modify(1, 0, end, brick[i].lid, brick[i].rid); memset(ans, 0, sizeof(ans)); query(1, 0, end); for(int i = 1; i <= m; i++) printf("%lld\n", ans[i]); puts(""); } return 0; }
相关文章推荐
- 正则表达式
- 二叉树的基本操作
- ubuntu 常用命令大全
- Android中BitmapFactory.Options详解
- Selenium2学习-023-WebUI自动化实战实例-021-获取浏览器显示区域大小,通过 WebDriver 截图功能
- UVa 232 Crossword Answers
- leetcode--Lowest Common Ancestor of a Binary Tree
- 链路层 - SLIP,PPP,
- 链路层 - SLIP,PPP,
- 欢迎使用CSDN-markdown编辑器
- 机试算法讲解: 第39题 DAG之QQ师徒关系
- Linux下Socket编程
- 士兵杀敌(一)
- HDU 5338 ZZX and Permutations 线段树
- 黑马程序员——多线程知识总结1
- 机试算法讲解: 第38题 求Dijkstra最短路径及花费
- inDensity,inTargetDensity,inScreenDensity关系详解
- JavaScript中的枚举类型
- 2524 矩形A + B
- [Leetcode] Maximal Square