题意:高度为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 }
poj2528-Mayor's posters-线段树离散化、基础
时间: 2024-10-29 04:35:22