POJ 2528 分块+离散化

Mayor's posters

Description

给出n张海报,每张海报的起点终点为l,r。

求依次贴在墙面后最终能看到的海报数。

Solution

由于海报贴的起点终点较大,但总的海报数较少,首先将海报的起点终点离散化。

不过普通离散化还有一些问题(wa了很久),如这个测试点

$3$

$1\ 10$

$1\ 3$

$6\ 10$

普通离散化后的对应关系为$1:1,3:2,6:3,10:4$

这样的话就会将$1\ 10$区间完全覆盖住,但实际上是不会的

解决这个冲突的办法是在相邻且相差大于1的节点中间再加入一个值。

离散化的问题解决后,就可以开数据结构搞了,不过在下憨憨用的是暴力分块。

和线段树一样记录一个lazy标记,在更改整个区间时下传标记。

最后统计答案。

  1 #include <algorithm>
  2 #include <cctype>
  3 #include <cmath>
  4 #include <cstdio>
  5 #include <cstdlib>
  6 #include <cstring>
  7 #include <iostream>
  8 #include <map>
  9 #include <numeric>
 10 #include <queue>
 11 #include <set>
 12 #include <stack>
 13 #if __cplusplus >= 201103L
 14 #include <unordered_map>
 15 #include <unordered_set>
 16 #endif
 17 #include <vector>
 18 #define lson rt << 1, l, mid
 19 #define rson rt << 1 | 1, mid + 1, r
 20 #define LONG_LONG_MAX 9223372036854775807LL
 21 #define pblank putchar(' ')
 22 #define ll LL
 23 #define fastIO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
 24 using namespace std;
 25 typedef long long ll;
 26 typedef long double ld;
 27 typedef unsigned long long ull;
 28 typedef pair<int, int> P;
 29 const int maxn = 1e4 + 10;
 30 int n, m, k, block_num, block_size, cnt;
 31 vector<int> v;
 32 int lft[maxn], rgt[maxn];
 33 int vis[maxn << 2];
 34 int cd[maxn << 2];
 35 struct Node
 36 {
 37     int l, r, lazy;
 38 } tr[maxn];
 39 inline int getid(int x)
 40 {
 41     return lower_bound(v.begin(), v.end(), x) - v.begin() + 1;
 42 }
 43 inline int getblock(int x)
 44 {
 45     int h = 1, t = block_num, res = -1;
 46     while (h <= t)
 47     {
 48         int mid = h + t >> 1;
 49         if (tr[mid].l <= x)
 50         {
 51             res = mid;
 52             h = mid + 1;
 53         }
 54         else
 55             t = mid - 1;
 56     }
 57     return res;
 58 }
 59 
 60 void build(int cnt)
 61 {
 62     block_size = (int)sqrt(cnt);
 63     block_num = cnt / block_size;
 64     if (cnt % block_size)
 65         block_num = block_size + 1;
 66     for (int i = 1; i <= block_num; i++)
 67     {
 68         tr[i].l = (i - 1) * block_size + 1;
 69         tr[i].r = i * block_size;
 70         tr[i].lazy = 0;
 71     }
 72     tr[block_num].r = cnt;
 73 }
 74 void push_down(int rt)
 75 {
 76     if (tr[rt].lazy)
 77     {
 78         for (int i = tr[rt].l; i <= tr[rt].r; i++)
 79             cd[i] = tr[rt].lazy;
 80         tr[rt].lazy = 0;
 81     }
 82 }
 83 inline void update(int L, int R, int idx)
 84 {
 85     int bl = getblock(L);
 86     int br = getblock(R);
 87     if (bl == br || bl + 1 == br)
 88     {
 89         push_down(bl);
 90         if (bl + 1 == br)
 91             push_down(br);
 92         for (int i = L; i <= R; i++)
 93             cd[i] = idx;
 94     }
 95     else
 96     {
 97         push_down(bl);
 98         push_down(br);
 99         for (int i = L; i <= tr[bl].r; i++)
100             cd[i] = idx;
101         for (int i = tr[br].l; i <= R; i++)
102             cd[i] = idx;
103         for (int i = bl + 1; i < br; i++)
104             tr[i].lazy = idx;
105     }
106 }
107 
108 int main(int argc, char const *argv[])
109 {
110 #ifndef ONLINE_JUDGE
111     freopen("in.txt", "r", stdin);
112     // freopen("out.txt", "w", stdout);
113 #endif
114     fastIO;
115     int t;
116     cin >> t;
117     while (t--)
118     {
119         v.clear();
120         cin >> n;
121         memset(vis, 0, sizeof(int) * (n + 1));
122         for (int i = 1; i <= n; i++)
123         {
124             cin >> lft[i] >> rgt[i];
125             v.push_back(lft[i]);
126             v.push_back(rgt[i]);
127         }
128         sort(v.begin(), v.end());
129         v.erase(unique(v.begin(), v.end()), v.end());
130         int tmp = v.size();
131         for (int i = 1; i < tmp; i++)
132             if (v[i] - v[i - 1] > 1)
133                 v.push_back(v[i - 1] + 1);
134         sort(v.begin(), v.end());
135         cnt = v.size();
136         build(cnt);
137         memset(cd, 0, sizeof(int) * (cnt + 1));
138         for (int i = 1; i <= n; i++)
139         {
140             int l = getid(lft[i]);
141             int r = getid(rgt[i]);
142             update(l, r, i);
143         }
144         for (int i = 1; i <= block_num; i++)
145         {
146             if (tr[i].lazy)
147                 vis[tr[i].lazy] = 1;
148             else
149             {
150                 for (int j = tr[i].l; j <= tr[i].r; j++)
151                     if (cd[j])
152                         vis[cd[j]] = 1;
153             }
154         }
155         cout << accumulate(vis + 1, vis + 1 + cnt, 0) << "\n";
156     }
157     return 0;
158 }
View Code

 

posted @ 2019-12-04 21:50  mool  阅读(256)  评论(0编辑  收藏  举报