洛谷P4137 Rmq Problem / mex 基础莫队

洛谷P4137 Rmq Problem / mex标签基础莫队前言我的csdn和博客园是同步的,欢迎来访danzh-博客园~很简单的莫队哦简明题意询问区间[L,R]中不存在的最小的数思路一看题,感觉莫队可以写。然后看看容不容易转移~首先remove,假设当前区间最小的不存在的数是ans。那么很显然的是,当前区间中一定存在[0,ans)中的所有数,ans这...
摘要由CSDN通过智能技术生成

洛谷P4137 Rmq Problem / mex


标签

  • 基础莫队

前言

  • 我的csdn和博客园是同步的,欢迎来访danzh-博客园~
  • 很简单的莫队哦

简明题意

  • 询问区间[L,R]中不存在的最小的数

思路

  • 一看题,感觉莫队可以写。然后看看容不容易转移~
  • 首先remove,假设当前区间最小的不存在的数是ans。那么很显然的是,当前区间中一定存在[0,ans)中的所有数,ans这个数肯定不存在,>ans的数全部都可能存在。所以现在remove操作只有两种情况,要么remove的是<ans的,要么remove的>ans。
  • remove的>ans,显然并不会影响答案(因为>ans的数就算全没了,ans那个数仍然不存在,所以答案仍然是ans),所以不需要更新答案,只需要开一个数组cnt[]记录每个数出现的次数。
  • remove的<ans。那么答案一定会更新吗?不一定的,判断一下remove的数出现的次数就能判断是否需要更新ans
  • 然后讲一讲add操作。大家可以举例,会发现,只有当添加一个和ans相等的数,才会影响答案。
  • 前面说过了,当前答案是ans时,当前区间一定存在[0,ans)中的所有数,所以你新加一个[1,ans)的数,并不影响答案。如果新加的数>ans,显然还是对答案没有影响,因为不管你怎么加数,ans那个数仍然不存在。现在唯一没有考虑的就是add一个==ans的数。
  • 当add一个==ans,答案一定会变。因为加了后ans就存在了嘛。问题是,加了之后,答案是什么呢?首先答案一定是>ans的。那么这里我的做法是从ans+1开始遍历一遍,一旦发现有一个数的cnt ==0,那么他就是答案了

注意事项

  • 这题看似应该离散化一下的(因为序列中的数的范围是1e9的,cnt数组就会炸掉),然而普通离散化会出问题,假如原数列是0,1,2,3,5,9999,233,4离散化后是0,1,2,3,5,7,6,4那么用离散化后的数跑一遍会发现[1,8]的答案是8,所以发现问题了吗?也就是普通离散化并没有维护原序列的连续性,而只维护了原序列的大小关系,所以导致错误。
  • 所以这里我有一个做法,是将原本连续的数离散成仍然连续的数,原本不连续的数离散时中间隔一个数。比如0,1,2,3,5,9999,233,4离散成0,1,2,3,5,9,7,4,现在查询[1,8]答案应该是6,就是答案。这个做法我还没实践,但是看起来是可行的~然而洛谷数据并没有把a[i]给的很大,所以不李三花也能过

总结

  • 做莫队最重要的就是转移了~

AC代码

#include<cstdio>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;

const int maxn = 2e5 + 10;

int pos[maxn];
struct Query
{
   
	int l, r, id;
	bool op
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值