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
", 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
原文地址:https://www.cnblogs.com/ZiningTang/p/3959509.html