Mayor's posters(線段樹+離散化)
阿新 • • 發佈:2019-03-02
++ 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 usingView Codenamespace 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; }
Mayor's posters(線段樹+離散化)