bzoj3339 bzoj3585
两题本质是一样,只不过3585要离散化
这种不修改,不强制的问题,显然先考虑离线算法
这道题的思路和bzoj1878非常像
考虑到如果只是求每个前缀的mex,我们是很容易扫一遍就得出来的
我们设为这个位置的mex
考虑从左往右依次删除当前数会对后面产生什么影响
我们设删除数a[i],a[i]下一个相同数的位置为next[a[i]]
显然对于[i+1,next[a[i]]-1]这些位置的mex可能有影响(如过没有next,就说明对后面所有位置都可能有影响);
凡是大于a[i]的一律都变成了a[i]
因此我们考虑对每个询问按左端点排序
然后从左往右依次删除a[i](按上述对后面位置进行修改)
不难发现,当某个询问左端点=当前位置i时(当然是先查询后删除了),这个询问的答案就是右端点上的mex,
显然修改操作我们可以用线段树来维护,这样就解决了这个问题
const inf=;
var loc,ans,next,last,sg,p,q,c,a,b:array[..] of longint;
tree:array[..] of longint;
d:array[..] of longint;
v:array[..] of boolean;
i,n,m,j,t,k:longint; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; function find(x:longint):longint;
var l,r,m:longint;
begin
l:=;
r:=t;
while l<=r do
begin
m:=(l+r) shr ;
if d[m]=x then exit(m);
if d[m]>x then r:=m- else l:=m+;
end;
end; procedure sort1(l,r:longint);
var i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=p[(l+r) div ];
repeat
while p[i]<x do inc(i);
while x<p[j] do dec(j);
if not(i>j) then
begin
swap(p[i],p[j]);
swap(q[i],q[j]);
swap(c[i],c[j]);
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort1(l,j);
if i<r then sort1(i,r);
end; procedure sort2(l,r:longint);
var i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=b[(l+r) div ];
repeat
while b[i]<x do inc(i);
while x<b[j] do dec(j);
if not(i>j) then
begin
swap(b[i],b[j]);
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort2(l,j);
if i<r then sort2(i,r);
end; procedure build(i,l,r:longint);
var m:longint;
begin
if l=r then
tree[i]:=sg[l]
else begin
tree[i]:=inf;
m:=(l+r) shr ;
build(i*,l,m);
build(i*+,m+,r);
end;
end; procedure push(i:longint);
begin
tree[i*]:=min(tree[i*],tree[i]);
tree[i*+]:=min(tree[i*+],tree[i]);
tree[i]:=inf;
end; procedure work(i,l,r,x,y,z:longint);
var m:longint;
begin
if (x<=l) and (y>=r) then
tree[i]:=min(tree[i],z)
else begin
if tree[i]<>inf then push(i);
m:=(l+r) shr ;
if x<=m then work(i*,l,m,x,y,z);
if y>m then work(i*+,m+,r,x,y,z);
end;
end; function ask(i,l,r,x:longint):longint;
var m:longint;
begin
if l=r then exit(tree[i])
else begin
if tree[i]<>inf then push(i);
m:=(l+r) shr ;
if x<=m then exit(ask(i*,l,m,x))
else exit(ask(i*+,m+,r,x));
end;
end; begin
readln(n,m);
for i:= to n do
begin
read(a[i]);
b[i]:=a[i];
end;
sort2(,n);
if b[]<> then
begin
inc(t);
d[]:=;
end;
inc(t);
d[t]:=b[];
for i:= to n do
begin
if b[i]=b[i-] then continue;
if b[i]-b[i-]> then
begin
inc(t);
d[t]:=b[i-]+;
end;
inc(t);
d[t]:=b[i];
end;
inc(t);
d[t]:=b[n]+;
k:=;
for i:= to n do
begin
loc[i]:=find(a[i]);
v[loc[i]]:=true;
while v[k] do inc(k);
sg[i]:=k;
end;
fillchar(last,sizeof(last),);
fillchar(next,sizeof(next),);
for i:=n downto do
begin
next[i]:=last[loc[i]];
last[loc[i]]:=i;
end; build(,,n);
for i:= to m do
begin
readln(p[i],q[i]);
c[i]:=i;
end; sort1(,m);
j:=;
for i:= to n do
begin
while p[j]=i do
begin
ans[c[j]]:=ask(,,n,q[j]);
inc(j);
end;
if next[i]=- then next[i]:=n+;
work(,,n,i+,next[i]-,loc[i]);
end;
for i:= to m do
writeln(d[ans[i]]);
end.
bzoj3339 bzoj3585的更多相关文章
- 分块+莫队||BZOJ3339||BZOJ3585||Luogu4137||Rmq Problem / mex
题面:P4137 Rmq Problem / mex 题解:先莫队排序一波,然后对权值进行分块,找出第一个没有填满的块,直接for一遍找答案. 除了bzoj3339以外,另外两道题Ai范围都是1e9. ...
- Rmq Problem/mex BZOJ3339 BZOJ3585
分析: 一开始没看懂题... 后来想用二分答案却不会验证... 之后,想到用主席树来维护... 建一个权值线段树,维护出这个权值以前所有的点最晚在哪里出现... 之后,查一下是不是比查询区间的l断点大 ...
- [BZOJ3585][BZOJ3339]mex
[BZOJ3585][BZOJ3339]mex 试题描述 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. 输入 第一行n,m.第二行为n个数.从 ...
- [bzoj3339]Rmq Problem||[bzoj3585]mex_线段树
Rmq Problem bzoj-3339||mex bzoj-3585 题目大意:给定一个长度为n的数列a,多次讯问区间l,r中最小的不属于集合{$A_l,A_{l+1}...A_r$}的非负整数. ...
- BZOJ3339:Rmq Problem & BZOJ3585 & 洛谷4137:mex——题解
前者:https://www.lydsy.com/JudgeOnline/problem.php?id=3339 后者: https://www.lydsy.com/JudgeOnline/probl ...
- 【bzoj3585/bzoj3339】mex/Rmq Problem 莫队算法+分块
原文地址:http://www.cnblogs.com/GXZlegend/p/6805283.html 题目描述 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没 ...
- 【BZOJ3585/3339】mex 莫队算法+分块
[BZOJ3585]mex Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. ...
- BZOJ3339 Rmq Problem
[bzoj3339]Rmq Problem Description Input Output Sample Input 7 5 0 2 1 0 1 3 2 1 3 2 3 1 4 3 6 2 7 Sa ...
- [BZOJ3585]mex(莫队+分块)
显然可以离线主席树,这里用莫队+分块做.分块的一个重要思想是实现修改与查询时间复杂度的均衡,这里莫队和分块互相弥补. 考虑暴力的分块做法,首先显然大于n的数直接忽略,于是将值域分成sqrt(n)份,每 ...
随机推荐
- PHP中的循环while、do...while、for、foreach四种循环。
php中的while循环,循环执行代码块制定的次数,或者当指定的条件为真时循环执行代码块. 在我们编写代码是时候,我们经常需要一块代码块重复执行多次.我们就可以使用while循环语句来完成这个任务. ...
- 在ASP中调用DLL的方法
.net的dll已经不是严格意义上的动态连接库了,而是一个类或者类库.它是不能直接在ASP.VB等其它的应用环境中使用的. 我们可以通过COM包装器(COM callable wrapper (C ...
- 详细查看数据库SQL执行计划
DBCC DROPCLEANBUFFERS 清除数据缓存DBCC FREEPROCCACHE 清除执行计划缓存 SET SHOWPLAN_XML ON 此语句导致 SQL Server 不执行 Tr ...
- Tensor神经网络进行知识库推理
本文是我关于论文<Reasoning With Neural Tensor Networks for Knowledge Base Completion>的学习笔记. 一.算法简介 网络的 ...
- Sprite Kit教程:初学者
作者:Ray Wenderlich 原文出处:点击打开链接 http://www.raywenderlich.com/42699/spritekit-tutorial-for-beginners 转自 ...
- JavaScript HTML DOM 元素(节点)
JavaScript HTML DOM 元素(节点) 创建新的 HTML 元素 创建新的 HTML 元素 如需向 HTML DOM 添加新元素,您必须首先创建该元素(元素节点),然后向一个已存在的元素 ...
- [中级] 有效删除URL中的index.php
如果你刚接触CI不久又或者刚刚研读CI的使用手册的话,关于如何有效删除URL中index.php以使URL看起来更友好美观的问题,可能是你面对的第一个较为复杂的问题!本贴不是原创,而是一个各种意见的综 ...
- 浅析CSS中的haslayout
作为一名web开发人员,最大的希望不是自己的水平有多高,而是希望浏览器厂家能够统一标准,相信任何一个只要是接触过web程序开发的人员都有那样的感受,就是浏览器之间的兼容性问题总是让我们的工作平添诸多的 ...
- Java操作hbase总结
用过以后,总得写个总结,不然,就忘喽. 一.寻找操作的jar包. java操作hbase,首先要考虑到使用hbase的jar包. 因为咱装的是CDH5,比较方便,使用SecureCRT工具,远程连接到 ...
- MATLAB中mexFunction函数的接口规范
MEX文件的调用极为方便,其调用方式与MATALAB的内建函数完全相同,只需要在命令窗口内输入对应的文件名称即可. C语言MEX程序代码文件有计算子例程(Computational routine)和 ...