1. 程式人生 > >Mayor's posters(線段樹+離散化)

Mayor's posters(線段樹+離散化)

++ main splay d3d close tree pac pair lin

這道題最關鍵的點就在離散化吧。

假如有三張海報[1, 10] [10, 13][15, 20] 僅僅三個區間就得占用到20了。

但是離散化後就可以是[1, 2] [2, 3] [4, 5] n到1e4 不重疊的話最大也只到2e4

那麽就可以做了

離散化技巧需要好好消化

代碼如下

技術分享圖片
#include <cstring>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define lp p<<1
#define rp p<<1|1
using
namespace std; const int N = 20000+5; int tree[N<<2]; int a[N], ans; bool vis[N]; pair<int,int> p[N]; inline void pushdown(int p) { if (tree[p]) { tree[lp] = tree[rp] = tree[p]; tree[p] = 0; } } void build(int p, int l, int r) { if (tree[p]) {
if (!vis[tree[p]]) { vis[tree[p]] = 1; ans++; } return; } int mid = l + r >> 1; build(lp, l, mid); build(rp, mid + 1, r); } void change(int p, int l, int r, int x, int y, int z) { if (x <= l && y >= r) { tree[p]
= z; return; } pushdown(p); int mid = l + r >> 1; if (x <= mid) change(lp, l, mid, x, y, z); if (y > mid) change(rp, mid + 1, r, x, y, z); } int main() { int T; scanf("%d", &T); while (T--) { int n; scanf("%d", &n); for (int i = 1; i <= 2 * n; i++) { scanf("%d", &p[i].first); p[i].second = i; } sort(p + 1, p + 2 * n + 1); int last = 0, cnt = 0; for (int i = 1; i <= 2 * n; i++) { if (p[i].first == last) { a[p[i].second] = cnt; } else { a[p[i].second] = ++cnt, last = p[i].first; } } memset(tree, 0, sizeof(tree)); for (int i = 1; i <= 2 * n; i += 2) { change(1, 1, cnt, a[i], a[i+1], (i + 1) / 2); } memset(vis, 0, sizeof(vis)); ans = 0; build(1, 1, cnt); printf("%d\n", ans); } return 0; }
View Code

Mayor's posters(線段樹+離散化)