zoukankan      html  css  js  c++  java
  • 【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
    ",ans[i]);
    102     return 0;
    103 }

     (……)

  • 相关阅读:
    【focus-lei 】微服务
    queryURLParams
    时间字符串的处理
    str.charAt()与str[]的区别
    数组去重函数封装
    数组去重的几种方法
    splice与slice区别
    变量与属性名的区别
    parseInt parseFloat Number三者转换的方式
    原生js实现选项卡样式切换的几种方式。
  • 原文地址:https://www.cnblogs.com/mjtcn/p/7341052.html
Copyright © 2011-2022 走看看