【bzoj3339】Rmq Problem

【bzoj3339】Rmq Problem

Description

Input

Output

Sample Input

7 5
0 2 1 0 1 3 2
1 3
2 3
1 4
3 6
2 7

Sample Output

3
0
3
2
4

HINT

分析

离线算法。

对于[l,r]区间的询问,我们可以线性求出来,然后考虑[l,r]与[l+1,r]区间有什么不同,在a[l]下一次出现的位置之前,所有大于a[l]的mex,都变成是a[l],因为 [l+1,a[l]下一次出现的位置-1],这个区间内没有a[l]了,大于它的数当然可以是它。

所以将询问的先按左端点排序,然后递增左端点,不断更新,用线段树维护。

code

 

  1 #include<cstdio>
  2 #include<algorithm>
  3 #define lson l,m,rt<<1
  4 #define rson m+1,r,rt<<1|1
  5 
  6 using namespace std;
  7 
  8 const int MAXN = 200100;
  9 const int INF = 1e9;
 10 
 11 struct Que{
 12     int l,r,id;
 13     bool operator < (const Que &x) const 
 14     {
 15         return l < x.l;
 16     }
 17 }q[MAXN];
 18 int a[MAXN],sg[MAXN],mn[MAXN<<2];
 19 int next[MAXN],last[MAXN],ans[MAXN];
 20 bool vis[MAXN];
 21 int n,m,k = 0,now;
 22 
 23 int read()
 24 {
 25     int x=0;char ch=getchar();
 26     while(ch<'0'||ch>'9') {ch=getchar(); }
 27     while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar(); }
 28     return x;
 29 }
 30 void pushdown(int rt)
 31 {
 32     if (mn[rt]!=INF)
 33     {
 34         mn[rt<<1] = min(mn[rt],mn[rt<<1]);
 35         mn[rt<<1|1] = min(mn[rt],mn[rt<<1|1]);
 36     }
 37 }
 38 void build(int l,int r,int rt)
 39 {
 40     mn[rt] = INF;
 41     if (l==r)
 42     {
 43         mn[rt] = sg[l];
 44         return ;
 45     }
 46     int m = (l+r)>>1;
 47     build(lson);
 48     build(rson);
 49 }
 50 void update(int l,int r,int rt,int L,int R,int v)
 51 {
 52     if (L<=l&&r<=R)
 53     {
 54         mn[rt] = min(mn[rt],v);
 55         return ;
 56     }
 57     pushdown(rt);
 58     int m = (l+r)>>1;
 59     if (L<=m) update(lson,L,R,v);
 60     if (R>m)  update(rson,L,R,v);
 61 }
 62 int query(int l,int r,int rt,int p)
 63 {
 64     if (l==r) return mn[rt];
 65     pushdown(rt);
 66     int m = (l+r)>>1;
 67     if (p<=m) return query(lson,p);
 68     else return query(rson,p);    
 69 }
 70 
 71 int main()
 72 {
 73     n = read();m = read();
 74     for (int i=1; i<=n; ++i)
 75         a[i] = read();
 76     for (int i=1;i<=m; ++i)
 77         q[i].l = read(), q[i].r = read(), q[i].id = i;
 78     sort(q+1,q+m+1);
 79     for (int i=1; i<=n; ++i)
 80     {
 81         vis[a[i]] = true;
 82         while (vis[k]) k++;
 83         sg[i] = k;
 84     }
 85     build(1,n,1);
 86     for (int i=n; i; --i)
 87         next[i] = last[a[i]], last[a[i]] = i;
 88     now = 1;
 89     
 90     for (int i=1; i<=m; ++i)
 91     {
 92         while (now<q[i].l)
 93         {
 94             if (!next[now]) next[now] = n+1;
 95             update(1,n,1,now,next[now]-1,a[now]);
 96             now++;
 97         }
 98         ans[q[i].id] = query(1,n,1,q[i].r);
 99     }
100     for (int i=1; i<=m; ++i)
101         printf("%d\n",ans[i]);
102     return 0;
103 }

 (……)

posted @ 2017-08-10 19:39  MJT12044  阅读(241)  评论(0编辑  收藏  举报