poj2528 Mayor's posters 线段树+离散化(经典)
来源:互联网 发布:安徽省癌症数据 编辑:程序博客网 时间:2024/06/06 00:08
题意:
市长竞选,每个市长都往墙上贴海报,海报之间彼此可以覆盖,给出粘贴顺序和每个海报的起点和长度,问最后有多少海报是可见的。
代码:
不是线段树新手应该能看懂,或者说做这题还是wa的同学,下面注释写的都是细节;
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define MAXN 10008using namespace std;struct Node{ int l, r, v;} lines[16*MAXN];struct item { int coord, id;} poster[4*MAXN];int n, T, li[MAXN], ri[MAXN], rini[MAXN*2];int res[MAXN];void build(int k, int l, int r) {//建树 lines[k].l = l; lines[k].r = r; lines[k].v = 0; if (l == r) return ; int mid = (l+r)/2; build(k*2, l, mid); build(k*2+1, mid+1, r); return ;}void query(int k, int l, int r, int i) {//节点更新 if (lines[k].l == l && lines[k].r == r) { lines[k].v = i; return ; } //若节点k已经被覆盖, 需先将k的子节点改成k的颜色,然后本身赋0; if (lines[k].v > 0) { lines[k*2].v = lines[k].v; lines[k*2+1].v = lines[k].v; lines[k].v = 0; } int mid = (lines[k].l+lines[k].r)/2; if (l > mid) query(k*2+1, l, r, i); else if (r <= mid) query(k*2, l, r, i); else { query(k*2, l, mid, i); query(k*2+1, mid+1, r, i); }}int dblup(int l, int r, int v) { //二分查找ID while (l <= r) { int mid = (l+r)/2; if (poster[mid].coord == v) return poster[mid].id; if (poster[mid].coord > v) r = mid-1; else l = mid+1; } return 0;}int cmp(item aa, item bb) { return aa.coord < bb.coord;}void getres(int k, int res[]) { if (lines[k].v > 0) { res[lines[k].v] = 1; return ; } if (lines[k].l == lines.r) return ;//并不是1~j-1都被覆盖了,少了会re; getres(2*k, res); getres(2*k+1, res);}int main() { //freopen("in.txt", "r", stdin); scanf("%d", &T); while (T--) { memset(res, 0, sizeof(res)); scanf("%d", &n); int j = 1; for(int i = 1; i <= n; i++) { scanf("%d%d", li+i, ri+i); rini[j++] = li[i];//把每一幅海报都记录下来,以便离散化; rini[j++] = ri[i]; } rini[j] = -1; sort(rini+1, rini+j); j = 1; for(int i = 1; i <= 2*n; i++,j++) { if (rini[i] - rini[i-1] > 1 && i != 1) {//距离大于一的,要加一个节点(不好解释); poster[j].coord = rini[i]-1; poster[j].id = j; j++; } poster[j].coord = rini[i]; poster[j].id = j; while (rini[i+1] == rini[i]) i++;//删除重复节点 } build(1, 1, j-1); for(int i = 1; i <= n; i++) { int aa = dblup(1, j-1, li[i]); int bb = dblup(1, j-1, ri[i]); query(1, aa, bb, i); } getres(1, res); int result = 0; for(int i = 1; i <= n; i++) if (res[i]) { result++; } printf("%d\n", result); } return 0;}
贴一个精简版, 就是把结构体改成了数组,减少了很多内存,时间复杂度并没有变;
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define MAXN 10008using namespace std;#define lson k<<1, l, mid#define rson k<<1|1, mid+1, rstruct item { int coord, id;} poster[4*MAXN];int n, T, li[MAXN], ri[MAXN], rini[MAXN*2], res[MAXN], lines[16*MAXN];void query(int li, int ri, int i, int k, int l, int r) { if ( li <= l && ri >= r) { lines[k] = i; return ; } if (lines[k] > 0) { lines[k*2] = lines[k*2+1] = lines[k]; lines[k] = 0; } int mid = (l+r)/2; if (li <= mid) query(li, ri, i, lson); if (ri > mid) query(li, ri, i, rson);}int dblup(int l, int r, int v) { while (l <= r) { int mid = (l+r)/2; if (poster[mid].coord == v) return poster[mid].id; if (poster[mid].coord > v) r = mid-1; else l = mid+1; } return 0;}int cmp(item aa, item bb) { return aa.coord < bb.coord;}void getres(int k, int l, int r, int res[]) { if (lines[k] > 0) { res[lines[k]] = 1; return ; } if (l == r) return ; int mid = (l+r)/2; getres(lson, res); getres(rson, res);}int main() { //freopen("in.txt", "r", stdin); scanf("%d", &T); while (T--) { memset(res, 0, sizeof(res)); memset(lines, 0, sizeof(lines)); scanf("%d", &n); int j = 1; for(int i = 1; i <= n; i++) { scanf("%d%d", li+i, ri+i); rini[j++] = li[i]; rini[j++] = ri[i]; } rini[j] = -1; sort(rini+1, rini+j); j = 1; for(int i = 1; i <= 2*n; i++,j++) { if (rini[i] - rini[i-1] > 1 && i != 1) { poster[j].coord = rini[i]-1; poster[j].id = j; j++; } poster[j].coord = rini[i]; poster[j].id = j; while (rini[i+1] == rini[i]) i++; } for(int i = 1; i <= n; i++) { int aa = dblup(1, j-1, li[i]); int bb = dblup(1, j-1, ri[i]); query(aa, bb, i, 1, 1, j-1); } getres(1, 1, j-1, res); int result = 0; for(int i = 1; i <= n; i++) if (res[i]) { result++; } printf("%d\n", result); } return 0;}
0 0
- poj2528 Mayor's posters 线段树+离散化(经典)
- Mayor's posters(POJ2528)(线段树+离散化)
- poj2528 Mayor's posters(线段树+离散化)
- poj2528 Mayor's posters(线段树,离散化)
- POJ2528 Mayor's posters(线段树+离散化)
- poj2528-Mayor's posters(线段树,区间,离散化)
- POJ2528-Mayor's posters(线段树+离散化)
- POJ2528:Mayor's posters(线段树区间更新+离散化)
- poj2528--Mayor's posters(线段树+离散化)
- poj2528 Mayor's posters,线段树,离散化
- poj2528 Mayor’s posters 线段树+离散化
- Mayor's posters(线段树+离散化POJ2528)
- POJ2528 Mayor's posters 线段树区间更新+离散化
- poj2528 Mayor's posters 线段树+离散化
- 【POJ2528】Mayor's Posters-线段树+离散化
- poj2528-Mayor's posters -离散化线段树
- poj2528 Mayor's posters 【线段树+离散化】
- poj2528 Mayor's posters 线段树离散化+lazy标记
- 关于接入百度语音的总结
- API Guide:绪论-设备兼容性
- pat 1061. Dating
- 动态规划练习-06(登山)
- pacp_loop函数的使用
- poj2528 Mayor's posters 线段树+离散化(经典)
- 01 邂逅Opencv
- Android与MVC设计模式
- oj_10 蚯蚓
- 关于几个主流语音SDK的接入问题
- 动态规划之图像压缩算法
- nyoj-过河问题
- C++中动态存储分配的基础知识
- java 的JVM内存详解和内存溢出异常