Luogu4137:Rmq Problem/mex

题面

传送门

Sol

这题可能是假的
离线莫队搞一搞,把数字再分块搞一搞,就行了

# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int _(2e5 + 5);

IL ll Input(){
    RG char c = getchar(); RG ll x = 0, z = 1;
    for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x * z;
}

int n, q, bl[_], val[_], ans[_], cnt[_], sum[_];
struct Qry{
    int l, r, id;
    IL bool operator <(RG Qry B) const{
        return bl[l] != bl[B.l] ? bl[l] < bl[B.l] : r < B.r;
    }
} qry[_];

IL void Modify(RG int x, RG int d){
    if(d > 0){
        if(!cnt[x]) ++sum[x / 500];
        ++cnt[x];
    }
    else{
        --cnt[x];
        if(!cnt[x]) --sum[x / 500];
    }
}

IL int Calc(){
    RG int ret = 0;
    for(RG int i = 0; ; ++i)
        for(RG int j = 0; j < 500 && sum[i] != 500; ++j)
            if(!cnt[i * 500 + j]) return i * 500 + j;
}

int main(RG int argc, RG char* argv[]){
    n = Input(); q = Input();
    RG int blo = sqrt(n);
    for(RG int i = 1; i <= n; ++i){
        val[i] = Input();
        bl[i] = (i - 1) / blo + 1;
    }
    for(RG int i = 1; i <= q; ++i) qry[i] = (Qry){Input(), Input(), i};
    sort(qry + 1, qry + q + 1);
    for(RG int L = qry[1].l, R = qry[1].l - 1, i = 1; i <= q; ++i){
        while(L < qry[i].l) Modify(val[L], -1), ++L;
        while(L > qry[i].l) --L, Modify(val[L], 1);
        while(R < qry[i].r) ++R, Modify(val[R], 1);
        while(R > qry[i].r) Modify(val[R], -1), --R;
        ans[qry[i].id] = Calc();
    }
    for(RG int i = 1; i <= q; ++i) printf("%d\n", ans[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/cjoieryl/p/8365238.html

时间: 2024-08-01 20:50:08

Luogu4137:Rmq Problem/mex的相关文章

【luogu4137】 Rmq Problem / mex - 莫队

题目描述 有一个长度为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 +

BZOJ3339:Rmq Problem &amp; BZOJ3585 &amp; 洛谷4137:mex——题解

前者:https://www.lydsy.com/JudgeOnline/problem.php?id=3339 后者: https://www.lydsy.com/JudgeOnline/problem.php?id=3585 https://www.luogu.org/problemnew/show/P4137 有一个长度为n的数组{a1,a2,…,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. 题解大部分都是莫队分块,但是复杂度为O(n*sqrt(n))=5e2*2e5=1e

Luogu P4137 Rmq Problem / mex

区间mex问题,可以使用经典的记录上一次位置之后再上主席树解决. 不过主席树好像不是很好写哈,那我们写莫队吧 考虑每一次维护什么东西,首先记一个答案,同时开一个数组记录一下每一个数出现的次数. 然后些比较显然的性质:如果加入一个数时,答案只会增加:同样的删除一个数时,答案只会减小 利用好这些性质我们就愉快地上莫队即可不过复杂度很迷,转移的时候只能近似\(O(1)\) CODE #include<cstdio> #include<cctype> #include<cmath&g

P4137 Rmq Problem / mex

思路 主席树维护mex 维护一下每个数上次出现的位置 [l,r]就是在r这颗线段树上查询位置小于l的最小的数 代码 #include <cstdio> #include <algorithm> #include <cstring> using namespace std; struct Node{ int lson,rson,minx; }Seg[200200*30]; int n,m,root[200200],Nodecnt,a[200200]; void pushu

Rmq Problem

大视野——3339: Rmq Problem Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1192  Solved: 620[Submit][Status][Discuss] Description Input Output Sample Input 7 50 2 1 0 1 3 21 32 31 43 62 7 Sample Output 30324 HINT Source By Xhr 思路: 对于这个题似乎暴力不好打,而且似乎强制在线操作

【题解】P4137 Rmq Problem(莫队)

[题解]P4137 Rmq Problem(莫队) 其实这道题根本就不用离散化! 因为显然有\(mex\)值是\(\le 2\times 10^5\)的,所以对于大于\(2\times 10^5\)的数我们可以忽略. 然后直接莫队算就是的,开一个\(2e5\)的桶 若一个比答案小的值的桶为\(0\)了:答案更新为它 若这个\(mex\)的桶突然有值了:暴力枚举答案变大,第一个桶里没值的就是答案,更新. 有小伙伴会问,这复杂度不上天了?其实不然.移动\(ans\)的总复杂度(好像)是\(O(n\s

【BZOJ】【3339】Rmq Problem

离线+线段树 Orz Hzwer,引用题解: 这一题在线似乎比较麻烦 至于离线.. 首先按照左端点将询问排序 然后一般可以这样考虑 首先如何得到1-i的sg值呢 这个可以一开始扫一遍完成 接着考虑l-r和l+1-r的答案有何不同 显然是l-next[l]-1这一段所有sg值大于a[l]的变为a[l] 这一步如果暴力修改的话只有30分 但是修改区间我们可以想到线段树,这样就能a了 晚上写题有点晕……忘了把当前时刻now置为q[i].l了,这种傻逼错误居然也犯…… 1 /**************

【BZOJ3489】A simple rmq problem kd-tree

[BZOJ3489]A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直接输出0.我会采取一些措施强制在线. Input 第一行为两个整数N,M.M是询问数,N是序列的长度(N<=100000,M<=200000) 第二行为N个整数,描述这个序列{ai},其中所有1<=ai<=N 再下面M行,每

【bzoj3339】Rmq Problem

[bzoj3339]Rmq Problem Description Input Output Sample Input 7 50 2 1 0 1 3 21 32 31 43 62 7 Sample Output 30324 HINT 分析 离线算法. 对于[l,r]区间的询问,我们可以线性求出来,然后考虑[l+1,r]区间有什么不同,在a[l]下一次出现的位置之前,所有大于a[l]的mex,都变成是a[l],因为 [l+1,a[l]下一次出现的位置-1],这个区间内没有a[l]了,大于它的数当然