[BZOJ3339]Rmq Problem / mex
Description:
有一个长度为n的数组{a1,a2,…,an}。m次询问,每次询问一个区间内最小没有出现过的自然数。
Hint:
\(n \le 2*10^5\)
Solution:
主席树好题,回滚莫队板子题?
把坐标离散化
不同于维护\(size\),这里用线段树维护以一个区间所有数的最后出现位置的最小值
这样我们每次直接在以\(r\)为根的值域线段树上找最小的\(val<l\)的数
// luogu-judger-enable-o2
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int mxn=8e6+100,mxm=1e7+5;
int n,m,s,p,cnt,tot,a[mxn],b[mxn],rt[mxm],tr[mxm],ls[mxm],rs[mxn];
inline int read() {
char c=getchar(); int x=0,f=1;
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
return x*f;
}
inline int chkmax(int &x,int y) {if(x<y) x=y;}
inline int chkmin(int &x,int y) {if(x>y) x=y;}
struct ed {
int to,nxt;
}t[mxn<<1];
void update(int las,int &p,int l,int r,int val,int pos)
{
if(!p) p=++cnt;
if(l==r) {tr[p]=val;return ;} int mid=(l+r)>>1;
if(pos<=mid) update(ls[las],ls[p],l,mid,val,pos),rs[p]=rs[las];
else update(rs[las],rs[p],mid+1,r,val,pos),ls[p]=ls[las];
tr[p]=min(tr[ls[p]],tr[rs[p]]);
}
int query(int p,int l,int r,int pos)
{
if((p == 0) or (l==r)) return b[l];
int mid=(l+r)>>1;
if(tr[ls[p]]>=pos) return query(rs[p],mid+1,r,pos);
else return query(ls[p],l,mid,pos);
}
int main()
{
n=read(); m=read(); int l,r; b[++tot]=0;
for(int i=1;i<=n;++i) a[i]=read(),b[++tot]=a[i],b[++tot]=a[i]+1;
sort(b+1,b+tot+1); s=unique(b+1,b+tot+1)-b-1;
for(int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+s+1,a[i])-b;
for(int i=1;i<=n;++i) update(rt[i-1],rt[i],1,s,i,a[i]);
for(int i=1;i<=m;++i) {
l=read(); r=read();
printf("%d\n",query(rt[r],1,s,l));
}
return 0;
}
常数极大的回滚莫队:
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=5e5+5;
int n,m,L,R,sz,num,res,a[mxn],b[mxn],bl[mxn],ans[mxn],bac[mxn];
inline int read() {
char c=getchar(); int x=0,f=1;
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
return x*f;
}
inline int chkmax(int &x,int y) {if(x<y) x=y;}
inline int chkmin(int &x,int y) {if(x>y) x=y;}
struct ed {
int to,nxt;
}t[mxn<<1];
struct Q {
int id,l,r;
}q[mxn];
int cmp(Q x,Q y) {
return bl[x.l]==bl[y.l]?x.r>y.r:bl[x.l]<bl[y.l];
}
void md(int x) {
if(a[x]<=n) {
--bac[a[x]];
if(bac[a[x]]==0) chkmin(res,a[x]);
}
}
void solve()
{
int l=1,r=0,z=1;
for(int i=1;i<=num;++i) {
L=(i-1)*sz; R=i*sz+1; res=n+1;
for(int j=0;j<=n;++j) bac[j]=0;
for(int j=1;j<=n;++j) if(a[j]<=n) ++bac[a[j]];
for(int j=0;j<=n;++j) if(!bac[j]) {res=j;break;}
l=-1,r=n+1; while(l<L-1) md(++l);
for(;bl[q[z].l]==i;++z) {
if(bl[q[z].l]==bl[q[z].r]) {
for(int k=q[z].l;k<=q[z].r;++k)
if(a[k]<=n) ++b[a[k]];
for(int k=0;k<=n;++k)
if(!b[k]) {ans[q[z].id]=k;break;}
for(int k=q[z].l;k<=q[z].r;++k)
if(a[k]<=n) --b[a[k]];
continue ;
}
while(r-1>q[z].r) md(--r); int las=res;
while(l<q[z].l-1) md(++l);
while(l>=L) {if(a[l]<=n) ++bac[a[l]]; --l;}
ans[q[z].id]=res; res=las;
}
}
}
int main()
{
n=read(); m=read(); sz=sqrt(n); int l,r; a[0]=n+1;
for(int i=1;i<=n;++i)
a[i]=read(),bl[i]=(i-1)/sz+1,chkmax(num,bl[i]);
for(int i=1;i<=m;++i)
q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+1,q+m+1,cmp); solve();
for(int i=1;i<=m;++i) printf("%d\n",ans[i]);
return 0;
}
[BZOJ3339]Rmq Problem / mex的更多相关文章
- 分块+莫队||BZOJ3339||BZOJ3585||Luogu4137||Rmq Problem / mex
题面:P4137 Rmq Problem / mex 题解:先莫队排序一波,然后对权值进行分块,找出第一个没有填满的块,直接for一遍找答案. 除了bzoj3339以外,另外两道题Ai范围都是1e9. ...
- BZOJ3339&&3585 Rmq Problem&&mex
BZOJ3339&&3585:Rmq Problem&&mex Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最 ...
- 【Luogu4137】Rmq Problem/mex (莫队)
[Luogu4137]Rmq Problem/mex (莫队) 题面 洛谷 题解 裸的莫队 暴力跳\(ans\)就能\(AC\) 考虑复杂度有保证的做法 每次计算的时候把数字按照大小也分块 每次就枚举 ...
- P4137 Rmq Problem / mex (莫队)
题目 P4137 Rmq Problem / mex 解析 莫队算法维护mex, 往里添加数的时候,若添加的数等于\(mex\),\(mex\)就不能等于这个值了,就从这个数开始枚举找\(mex\): ...
- 主席树||可持久化线段树+离散化 || 莫队+分块 ||BZOJ 3585: mex || Luogu P4137 Rmq Problem / mex
题面:Rmq Problem / mex 题解: 先离散化,然后插一堆空白,大体就是如果(对于以a.data<b.data排序后的A)A[i-1].data+1!=A[i].data,则插一个空 ...
- 洛谷 P4137 Rmq Problem /mex 解题报告
P4137 Rmq Problem /mex 题意 给一个长为\(n(\le 10^5)\)的数列\(\{a\}\),有\(m(\le 10^5)\)个询问,每次询问区间的\(mex\) 可以莫队然后 ...
- BZOJ 3339 && luogu4137 Rmq Problem / mex(莫队)
P4137 Rmq Problem / mex 题目描述 有一个长度为n的数组{a1,a2,-,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. 输入输出格式 输入格式: 第一行n,m. ...
- [bzoj3585] Rmq Problem / mex
[bzoj3585] Rmq Problem / mex bzoj luogu 看上一篇博客吧,看完了这个也顺理成章会了( (没错这篇博客就是这么水) #include<cstdio> # ...
- [bzoj3339]Rmq Problem||[bzoj3585]mex_线段树
Rmq Problem bzoj-3339||mex bzoj-3585 题目大意:给定一个长度为n的数列a,多次讯问区间l,r中最小的不属于集合{$A_l,A_{l+1}...A_r$}的非负整数. ...
随机推荐
- windows下使用Play框架
play类似于Spring这里的web框架.特点:MVC.函数编程. 版本:play 2.1.3 一.play命令 #play ~compile 功能:持续编译.在cmd中运行这个命令,只要 ...
- MySQL 官方 Docker 镜像的使用
首先是pull image,这里我拉取的是5.6.35: $ sudo docker pull mysql:5.6.35 拉下来以后大可以按照官方的说明无脑启动,但是外部无法访问,所以绑定端口: $ ...
- 【AtCoder】ARC073
ARC 073 C - Sentou 直接线段覆盖即可 #include <bits/stdc++.h> #define fi first #define se second #defin ...
- 分布式一致性算法——paxos
一.什么是paxos算法 Paxos 算法是分布式一致性算法用来解决一个分布式系统如何就某个值(决议)达成一致的问题. 人们在理解paxos算法是会遇到一些困境,那么接下来,我们带着以下几个问题来学习 ...
- MySQL事务提交过程(一)
MySQL作为一种关系型数据库,已被广泛应用到互联网中的诸多项目中.今天我们来讨论下事务的提交过程. MySQL体系结构 由于mysql插件式存储架构,导致开启binlog后,事务提交实质是二阶段提交 ...
- NSL:CPK_NN神经网络实现预测哪个样本与哪个样本处在同一层,从而科学规避我国煤矿突水灾难—Jason niu
load water_data.mat attributes = mapminmax(attributes); P_train = attributes(:,1:35); T_train = clas ...
- ♣eclipse护眼颜色和关键字颜色设置
eclipse护眼颜色和字体大小设置 ♣eclipse护眼颜色和关键字颜色设置 ♣eclipse字体大小设置(包括jsp , .xml ,.java) 1.Eclipse字体大小调整: 窗口(Wi ...
- mysql 数据库(二)数据库的基本操作
mysql 数据库(二)数据库的基本操作 用户管理,添加权限,创建,显示,使用数据库 1 显示数据库:show databases; 默认数据库: mysql - 用户权限相关数据 test - 用于 ...
- Farewell Party-构造
Farewell Party 思路 : 转换思路 ,有 a [ i ] 个不相等的 ,那么至少得有 n - a [ i ]个与它相等的. 但是有可能与它拥有相同数目的有很多. 但是为了能够最终 分配成 ...
- web服务搭建