两题本质是一样,只不过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的更多相关文章

  1. 分块+莫队||BZOJ3339||BZOJ3585||Luogu4137||Rmq Problem / mex

    题面:P4137 Rmq Problem / mex 题解:先莫队排序一波,然后对权值进行分块,找出第一个没有填满的块,直接for一遍找答案. 除了bzoj3339以外,另外两道题Ai范围都是1e9. ...

  2. Rmq Problem/mex BZOJ3339 BZOJ3585

    分析: 一开始没看懂题... 后来想用二分答案却不会验证... 之后,想到用主席树来维护... 建一个权值线段树,维护出这个权值以前所有的点最晚在哪里出现... 之后,查一下是不是比查询区间的l断点大 ...

  3. [BZOJ3585][BZOJ3339]mex

    [BZOJ3585][BZOJ3339]mex 试题描述 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. 输入 第一行n,m.第二行为n个数.从 ...

  4. [bzoj3339]Rmq Problem||[bzoj3585]mex_线段树

    Rmq Problem bzoj-3339||mex bzoj-3585 题目大意:给定一个长度为n的数列a,多次讯问区间l,r中最小的不属于集合{$A_l,A_{l+1}...A_r$}的非负整数. ...

  5. BZOJ3339:Rmq Problem & BZOJ3585 & 洛谷4137:mex——题解

    前者:https://www.lydsy.com/JudgeOnline/problem.php?id=3339 后者: https://www.lydsy.com/JudgeOnline/probl ...

  6. 【bzoj3585/bzoj3339】mex/Rmq Problem 莫队算法+分块

    原文地址:http://www.cnblogs.com/GXZlegend/p/6805283.html 题目描述 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没 ...

  7. 【BZOJ3585/3339】mex 莫队算法+分块

    [BZOJ3585]mex Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. ...

  8. 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 ...

  9. [BZOJ3585]mex(莫队+分块)

    显然可以离线主席树,这里用莫队+分块做.分块的一个重要思想是实现修改与查询时间复杂度的均衡,这里莫队和分块互相弥补. 考虑暴力的分块做法,首先显然大于n的数直接忽略,于是将值域分成sqrt(n)份,每 ...

随机推荐

  1. eclipse-SDK-3.7-win32;eclipse-java-indigo-win32;eclipse-jee-indigo-win32 区别(ZZ)

    eclipse-SDK-3.7-win32:eclipse-java-indigo-win32:eclipse-jee-indigo-win32 三个都是用于win32,即windows系统的32位机 ...

  2. HTTP协议 状态码详解

    http://www.cnblogs.com/TankXiao/archive/2013/01/08/2818542.html

  3. css兼容性问题

    其实做网页最大的问题还是兼容性吧,要调试IE的各种浏览器. DIV+CSS设计IE6.IE7.FF 兼容性  DIV+CSS网页布局这是一种趋势,我也开始顺应这股趋势了,不过在使用DIV+CSS网站设 ...

  4. Weex 样式

    1.盒型 width height padding padding-left padding-right padding-top padding-bottom margin margin-left m ...

  5. Java-Hirbernate小结大纲

    Hibernate Hibernate是一个开放源代码的对象关系映射框架 Hibernate的核心接口一共有6个,分别为:Session.SessionFactory.Transaction.Quer ...

  6. Android四大组件之一:ContentProvider(内容提供者)

    Android中还提供了名为ContentProvider(内容提供者),可以向其他应用提供数据,但不常用,除非是同一公司开发的App,可以向不同应用提供数据.虽然为Android的四大组件之一,但用 ...

  7. iOS6以后的单个控制器横竖屏显示以及旋转屏控制技巧,附带iOS8以后显示电池状态栏

    一.在应用中从竖屏模式强制转换为横屏模式 第一种方法:通过模态弹出视图的方式,使得特定ViewController坚持特定的interfaceOrientation(1)iOS6之后提供了这样一个方法 ...

  8. JavaScript Boolean(布尔) 对象

    创建 Boolean 对象 Boolean 对象代表两个值:"true" 或者 "false" 下面的代码定义了一个名为 myBoolean 的布尔对象: va ...

  9. 【转】WF4.0 (基础篇)

    转自:http://www.cnblogs.com/foundation/category/215023.html 作者:WXWinter  ——  兰竹菊梅★春夏秋冬☆ —— wxwinter@16 ...

  10. 不带头结点的单链表递归删除元素为X的结点

    #include <iostream> using namespace std; struct Node { Node *next; int elem; }; void creatList ...