[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$}的非负整数. ...
随机推荐
- Just Oj 2017C语言程序设计竞赛高级组D: 字符串最大表示(next数组)
D: 字符串最大表示 时间限制: 1 s 内存限制: 128 MB 题目描述 有如下定义,abcnabcn表示字符串abc重复n次,例如abc2abc2表示abcabc. 给定一个字符串,求 ...
- 20165206第4次实验《Android程序设计》实验报告
20165206第4次实验<Android程序设计>实验报告 一.实验报告封面 课程:Java程序设计 班级:1652班 姓名:韩啸 学号:20165206 指导教师:娄嘉鹏 实验日期:2 ...
- azkaban group分组,权限
翻译自:https://azkaban.readthedocs.io/en/latest/userManager.html?highlight=group 1.job project,名为" ...
- 007-Python函数-装饰器
函数回顾 1.函数可以当做一个参数赋值给另一个函数: def func(): print("in the func") def foo(x): x() foo(func) 输出: ...
- Django-model聚合查询与分组查询
Django-model聚合查询与分组查询 聚合函数包含:SUM AVG MIN MAX COUNT 聚合函数可以单独使用,不一定要和分组配合使用:不过聚合函数一般和group by 搭配使用 agg ...
- UIDebuggingInformationOverlay 调试
https://archimboldi.me/posts/%E7%BF%BB%E8%AF%91-uidebugginginformationoverlay.html http://ryanipete. ...
- ajax请求头加Token时发生的跨域(CORS)请求问题
首先描述下问题:需求是在请求头中加入token,我在ajax请求数据时添加了请求头‘Authorization’字段,并添加了响应的token值,在请求数据的时候浏览器报错如下: Request he ...
- 关于浏览器对html, js,css的解析先后顺序的理解
1.首先要了解页面的结构(包含哪些元素?哪些计算机语言能够在页面中运行 ) (1)html 不仅可以包含文字,还可以包含图片.链接,甚至音乐.程序等非文字元素的标记语言 ...
- Eclipse+Maven整合开发Java项目(二)➣webapp3.0以上的Maven项目
概述 Eclipse集成Maven插件,新建maven-archetype-webapp项目的时候,采用的webapp的版本较低,默认是2.3,有些时候,我们希望升级Webapp的版本到3.0(Tom ...
- A - Exposition CodeForces - 6E
题目链接:https://vjudge.net/contest/202699#problem/A 题意 给一个n个元素的序列,从中挑出最长的子序列,要求子序列中元素差的最大值不超过k.问有几个最长子序 ...