【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 }

猜你喜欢

转载自www.cnblogs.com/MisakaAzusa/p/8946492.html