1. 程式人生 > >Luogu 4137 Rmq Problem / mex

Luogu 4137 Rmq Problem / mex

har roo clas namespace eve 離線 root mes void

一個主席樹題。

一開始想著直接動態開點硬搞就可以了,每次查詢只要作一個類似於前綴和的東西看看區間有沒有滿,在主席樹上二分就可以了。

但是這樣是錯的,因為一個權值會出現很多次……然後就錯了。

所以我們考慮記錄每一個權值最後出現的位置,直接開權值下標記錄每一個權值最後出現的位置,因為是區間查詢,所以可持久化一下,這樣答案就是第一次出現位置小於$l$的最小權值,查詢方法類似。

考慮到答案只可能是$a_{i} + 1, 0$,所以直接大力把$a_{i}, a_{i} + 1,0$都丟進去離散化。

註意線段樹中權值0出現的位置不是inf,因為0也算自然數。

感覺離線下來也可以不用寫可持久化。

自己一開始還是naive

Code:

技術分享圖片
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 4e5 + 5;
const int M = 5e6 + 5;
const int inf = 1 << 30;

int n, qn, tot = 0, a[N], b[N];

inline void read(int &X) {
    X = 0;
    char ch = 0
; int op = 1; for(; ch > 9 || ch < 0; ch = getchar()) if(ch == -) op = -1; for(; ch >= 0 && ch <= 9; ch = getchar()) X = (X << 3) + (X << 1) + ch - 48; X *= op; } inline int min(int x, int y) { return x > y ? y : x; }
namespace PSegT { struct Node { int lc, rc, data; } s[M]; int root[N], nodeCnt; #define mid ((l + r) >> 1) inline void up(int p) { if(p) s[p].data = min(s[s[p].lc].data, s[s[p].rc].data); } void ins(int &p, int l, int r, int x, int pre, int v) { p = ++nodeCnt; s[p].lc = s[pre].lc, s[p].rc = s[pre].rc; if(l == r) { s[p].data = v; return; } if(x <= mid) ins(s[p].lc, l, mid, x, s[pre].lc, v); else ins(s[p].rc, mid + 1, r, x, s[pre].rc, v); up(p); } int query(int p, int l, int r, int x) { if(!p || l == r) return b[l]; if(s[s[p].lc].data < x) return query(s[p].lc, l, mid, x); else return query(s[p].rc, mid + 1, r, x); } } using namespace PSegT; int main() { read(n), read(qn); b[++tot] = 0; for(int i = 1; i <= n; i++) { read(a[i]); b[++tot] = a[i], b[++tot] = a[i] + 1; } sort(b + 1, b + tot + 1); tot = unique(b + 1, b + 1 + tot) - b - 1; root[0] = nodeCnt = 0; //s[0].data = inf; for(int i = 1; i <= n; i++) { a[i] = lower_bound(b + 1, b + 1 + tot, a[i]) - b; ins(root[i], 1, tot, a[i], root[i - 1], i); } for(int x, y; qn--; ) { read(x), read(y); printf("%d\n", query(root[y], 1, tot, x)); } return 0; }
View Code

Luogu 4137 Rmq Problem / mex