首页 > 代码库 > poj2528-Mayor's posters-线段树离散化、基础

poj2528-Mayor's posters-线段树离散化、基础

题意:高度为1byte的n(n <= 10000)张海报贴在高度为1byte长度为10000000byte的板上。海报按顺序张贴,给出每张海报的张贴范围,求最后能够看见多少张海报(不完整的都算)。

思路:因为数组不可能开10^7那么大,而且海报的张数只有10000张,则边界值最多20000个,于是我们离散化坐标值,这里用到了sort、unique、还有lower_bound去二分查找。用sort排序,unique去重后的数组的元素个数建线段树,之后,就是线段树的区间操作、lazy标记了。线段树记录当前是第几次被张贴,最后单点查询,不同的张贴数表示能看到的海报数,这里用一个vis数组去记录。

 

AC代码:

  1 #include <iostream>  2 #include <cstdio>  3 #include <algorithm>  4 #include <vector>  5 #include <cstring>  6 using namespace std;  7 #define lson l, m, rt<<1  8 #define rson m+1, r, rt<<1|1  9 #define maxn 20000 10 struct node 11 { 12     int l, r; 13 }; 14 int sgt[maxn<<2]; 15 vector<node> arr; 16 vector<int> sor; 17 int lazy[maxn<<2]; 18 bool vis[maxn]; 19 void input() 20 { 21     arr.clear(); 22     sor.clear(); 23     int n; scanf("%d", &n); 24     for(int i = 0; i < n; i++) { 25         node x; scanf("%d%d", &x.l, &x.r); 26         arr.push_back(x); 27         sor.push_back(x.l); 28         sor.push_back(x.r); 29     } 30     sort(sor.begin(), sor.end()); 31     vector<int>::iterator it; 32     it = unique(sor.begin(), sor.end()); 33     sor.resize(distance(sor.begin(), it)); 34     memset(vis, 0, sizeof(vis)); 35     memset(lazy, 0, sizeof(lazy)); 36 } 37 void push_down(int rt) 38 { 39     if(lazy[rt] != 0) { 40         lazy[rt<<1] = lazy[rt]; 41         lazy[rt<<1|1] = lazy[rt]; 42         sgt[rt<<1] = lazy[rt]; 43         sgt[rt<<1|1] = lazy[rt]; 44         lazy[rt] = 0; 45     } 46 } 47 void build(int l, int r, int rt) 48 { 49     lazy[rt] = 0; 50     if(l == r) { 51         sgt[rt] = 0; 52         return; 53     } 54     int m = (l+r)>>1; 55     build(lson); 56     build(rson); 57 } 58 void change(int l, int r, int rt, int L, int R, int del) 59 { 60     if(L <= l && r <= R) { 61         lazy[rt] = del; 62         sgt[rt] = del; 63         return; 64     } 65     push_down(rt); 66     int m = (l + r)>>1; 67     if( L <= m) change(lson, L, R, del); 68     if(m < R) change(rson, L, R, del); 69 } 70 void query(int l, int r, int rt) 71 { 72     if(l == r) { 73         vis[sgt[rt]] = 1; 74         return; 75     } 76     push_down(rt); 77     int m = (l+r)>>1; 78     query(lson); 79     query(rson); 80 } 81 void num() 82 { 83     int ans = 0; 84     int l = sor.size(); 85     for(int i = 1; i <= l; i++) { 86         if(vis[i] != 0) ans ++; 87     } 88     printf("%d\n", ans); 89 } 90  91 void work() 92 { 93     input(); 94     int n = sor.size(); 95     build(1, n, 1); 96     int len = arr.size(); 97     for(int i = 0; i < len; i++){ 98         int l = lower_bound(sor.begin(), sor.end(), arr[i].l) - sor.begin()+1; 99         int r = lower_bound(sor.begin(), sor.end(), arr[i].r) - sor.begin()+1;100         change(1, n, 1, l, r, i+1);101     }102     query(1, n, 1);103     num();104 }105 int main()106 {107     int t; scanf("%d", &t);108     while(t--) work();109     return 0;110 }
View Code

 

poj2528-Mayor's posters-线段树离散化、基础