【luogu P4137 Rmq Problem / mex】 题解
题目链接:https://www.luogu.org/problemnew/show/P4137
求区间内最大没出现过的自然数
在add时要先判断会不会对当前答案产生影响,如果有就去找下一个答案。
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cmath> 5 using namespace std; 6 const int maxn = 2e5+10; 7 int curL = 1, curR = 0, n, m, a[maxn], answer = 0, bl, cnt[maxn], ans[maxn]; 8 struct query{ 9 int l, r, p; 10 }q[maxn]; 11 inline int read() 12 { 13 int ret=0; 14 char c=getchar(); 15 while (c<'0' || c>'9') c=getchar(); 16 while (c>='0' && c<='9'){ 17 ret=((ret<<3)+(ret<<1))+c-'0'; 18 c=getchar(); 19 } 20 return ret; 21 } 22 bool cmp(const query &a, const query &b) 23 { 24 if(a.l / bl == b.l / bl) return a.r < b.r; 25 else return a.l < b.l; 26 } 27 void add(int pos) 28 { 29 cnt[a[pos]]++; 30 if(cnt[a[pos]] == 1 && answer==a[pos]) 31 { 32 while(cnt[answer]!=0) answer++; 33 } 34 } 35 inline void remove(int pos) 36 { 37 cnt[a[pos]]--; 38 if (cnt[a[pos]]==0) answer=min(answer,a[pos]); 39 } 40 int main() 41 { 42 n = read(); m = read(); 43 bl = sqrt(n); 44 45 for(int i = 1; i <= n; i++) 46 a[i] = read(); 47 48 for(int i = 1; i <= m; i++) 49 { 50 q[i].l = read(); q[i].r = read(); 51 q[i].p = i; 52 } 53 sort(q+1,q+1+m,cmp); 54 for(int i = 1; i <= m; i++) 55 { 56 int L = q[i].l, R = q[i].r; 57 while(curL < L) remove(curL++); 58 while(curL > L) add(--curL); 59 while(curR < R) add(++curR); 60 while(curR > R) remove(curR--); 61 ans[q[i].p] = answer; 62 } 63 for(int i = 1; i <= m; i++) 64 printf("%d\n",ans[i]); 65 return 0; 66 }
隐约雷鸣,阴霾天空,但盼风雨来,能留你在此。
隐约雷鸣,阴霾天空,即使天无雨,我亦留此地。