码迷,mamicode.com
首页 > 其他好文 > 详细

【luogu4137】 Rmq Problem / mex - 莫队

时间:2018-03-24 23:58:42      阅读:333      评论:0      收藏:0      [点我收藏+]

标签:namespace   struct   bre   for   出现   while   add   http   min   

题目描述

有一个长度为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 - 莫队

标签:namespace   struct   bre   for   出现   while   add   http   min   

原文地址:https://www.cnblogs.com/lrj124/p/8641631.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!