1. 程式人生 > >【luogu4137】 Rmq Problem / mex - 莫隊

【luogu4137】 Rmq Problem / mex - 莫隊

min pro .html 一個 rmq scanf pri 莫隊算法 i++

題目描述

有一個長度為n的數組{a1,a2,…,an}。m次詢問,每次詢問一個區間內最小沒有出現過的自然數。

輸入輸出格式

輸入格式:

第一行n,m。

第二行為n個數。

從第三行開始,每行一個詢問l,r。

輸出格式:

一行一個數,表示每個詢問的答案。

思路

莫隊算法詳見『這裏』

其實這題也不是莫隊

a高達10^9,只能說是

數據水2333333333

#include <bits/stdc++.h>
using namespace std;
const int maxn = 200000 + 10;
int n,m,now,block,cnt[maxn],a[maxn],ans[maxn];
struct Query { int l,r,num; inline bool operator < (Query cmp) const { if (l/block != cmp.l/block) return l/block < cmp.l/block; return r < cmp.r; } }q[maxn]; inline void add(int x) { if (x > n+1) return; cnt[x]++; if (now == x && cnt[x] > 0
) for (int i = x;i <= n+1;i++) if (!cnt[i]) { now = i; break; } } inline void del(int x) { if (x > n+1) return; cnt[x]--; if (!cnt[x]) now = min(now,x); } int main() { scanf("%d%d",&n,&m); block
= sqrt(n); a[0] = n+2; for (int i = 1;i <= n;i++) scanf("%d",&a[i]); for (int i = 1;i <= m;i++) { scanf("%d%d",&q[i].l,&q[i].r); q[i].num = i; } sort(q+1,q+m+1); int l = 0,r = 0; for (int i = 1;i <= m;i++) { while (l < q[i].l) del(a[l++]); while (l > q[i].l) add(a[--l]); while (r < q[i].r) add(a[++r]); while (r > q[i].r) del(a[r--]); ans[q[i].num] = now; } for (int i = 1;i <= m;i++) printf("%d\n",ans[i]); return 0; }

【luogu4137】 Rmq Problem / mex - 莫隊