BZOJ.3585.mex(线段树)
题意:多次求区间\(mex\)。
考虑\([1,i]\)的\(mex[i]\),显然是单调的
而对于\([l,r]\)与\([l+1,r]\),如果\(nxt[a[l]]>r\),那么\([l+1,r]\)中所有\(>a[l]\)的数显然要改成\(a[l]\)
把询问按左端点排序;离散化,预处理下\(nxt[]\),处理出\([1,i]\)的\(mex[i]\)。剩下就是线段树的区间更新、单点查询了
/*
离散化的时候>=n的全部看做n就好了
查询时是只需查r点的(l之前能更新r的已经更新完了,初始时是[1,r],r点现在就是[l,r]了)
单点即可不需要PushUp(也不好得某个区间的mex)
非叶节点上的mex完全可以代替tag
离散化需要注意 其实不是很懂这
*/
#include<cstdio>
#include<cctype>
#include<algorithm>
#define gc() getchar()
#define now node[rt]
#define lson node[node[rt].ls]
#define rson node[node[rt].rs]
const int N=2e5+5,INF=1e7;
int n,m,A[N],mex[N]/*不要和A混用*/,tmp[N],nxt[N],las[N],ans[N];
bool vis[N];
struct Ques
{
int l,r,id;
Ques() {}
Ques(int l,int r,int id): l(l),r(r),id(id) {}
bool operator <(const Ques &x)const {return l<x.l;}
}q[N];
struct Seg_Tree
{
int tot;
struct Node
{
int ls,rs,mex;
}node[N<<1];
inline void Upd(int &x,int v) {x=std::min(x,v);}
inline void PushDown(int rt)
{
Upd(lson.mex,now.mex), Upd(rson.mex,now.mex);
now.mex=INF;
}
void Build(int l,int r)
{
int rt=tot++;
if(l==r) now.mex = mex[l];
else
{
int m=l+r>>1; now.mex=INF;
now.ls=tot, Build(l,m);
now.rs=tot, Build(m+1,r);
}
}
void Update(int l,int r,int rt,int L,int R,int v)
{
if(L<=l && r<=R) Upd(now.mex,v);
else
{
if(now.mex<INF) PushDown(rt);
int m=l+r>>1;
if(L<=m) Update(l,m,now.ls,L,R,v);
if(m<R) Update(m+1,r,now.rs,L,R,v);
}
}
int Query(int l,int r,int rt,int p)
{
if(l==r) return now.mex;
if(now.mex<INF) PushDown(rt);
int m=l+r>>1;
if(p<=m) return Query(l,m,now.ls,p);
else return Query(m+1,r,now.rs,p);
}
}t;
#undef now
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
int Find(int x,int r)
{
int l=1,m;
while(l<r)
{
if(tmp[(m=l+r>>1)]<x) l=m+1;
else r=m;
}
return l;
}
int main()
{
n=read(),m=read();
for(int i=1; i<=n; ++i) tmp[i]=A[i]=std::min(n,read());
std::sort(tmp+1,tmp+1+n);
int cnt=1;
for(int i=2; i<=n && !(tmp[i]==n&&tmp[i+1]==n); ++i)
if(tmp[i]!=tmp[i-1]) tmp[++cnt]=tmp[i];
for(int k=0,p,i=1; i<=n; ++i)
{
vis[p=Find(A[i],cnt)]=1;
if(A[i]==k)//只有在当前最小值出现时才更新。。mex...
while(vis[p])//p-1,vis[k]?
{
++k;
if(tmp[++p]!=k) break;//离散化后
}
mex[i]=k;
}
t.Build(1,n);
for(int i=0; i<=n; ++i) las[i]=n+1;
for(int tp,i=n; i; --i) nxt[i]=las[tp=Find(A[i],cnt)], las[tp]=i;//!
for(int l,i=1; i<=m; ++i) l=read(), q[i]=Ques(l,read(),i);
std::sort(q+1,q+1+m);
for(int now=1,i=1; i<=m; ++i)
{
while(now<q[i].l)
t.Update(1,n,0,now+1,nxt[now]-1,A[now]), ++now;
ans[q[i].id]=t.Query(1,n,0,q[i].r);
}
for(int i=1; i<=m; ++i) printf("%d\n",ans[i]);
return 0;
}
BZOJ.3585.mex(线段树)的更多相关文章
- bzoj 3585 mex - 线段树 - 分块 - 莫队算法
Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问 ...
- BZOJ 3585: mex [主席树]
3585: mex Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 787 Solved: 422[Submit][Status][Discuss] ...
- BZOJ.4184.shallot(线段树分治 线性基)
BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...
- [BZOJ 4025]二分图(线段树分治+带边权并查集)
[BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...
- 主席树||可持久化线段树+离散化 || 莫队+分块 ||BZOJ 3585: mex || Luogu P4137 Rmq Problem / mex
题面:Rmq Problem / mex 题解: 先离散化,然后插一堆空白,大体就是如果(对于以a.data<b.data排序后的A)A[i-1].data+1!=A[i].data,则插一个空 ...
- BZOJ 3585: mex( 离线 + 线段树 )
离线, 询问排序. 先处理出1~i的答案, 这样可以回答左端点为1的询问.完成后就用seq(1)将1到它下一次出现的位置前更新. 不断这样转移就OK了 ------------------------ ...
- bzoj 3585: mex && 3339: Rmq Problem -- 主席树
3585: mex Time Limit: 20 Sec Memory Limit: 128 MB Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区 ...
- HDU-4747 Mex 线段树
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747 题意:求一个数列中,所有mex(L,R)的和. 注意到mex是单调不降的,那么首先预处理出mex ...
- 【BZOJ 3476】 线段树===
59 懒惰的奶牛贝西所在的牧场,散落着 N 堆牧草,其中第 i 堆牧草在 ( Xi,Yi ) 的位置,数量有 Ai 个单位.贝西从家移动到某一堆牧草的时候,只能沿坐标轴朝正北.正东.正西.正南这四个 ...
随机推荐
- Java探针-Java Agent技术-阿里面试题
Java探针参考:Java探针技术在应用安全领域的新突破 最近面试阿里,面试官先是问我类加载的流程,然后问了个问题,能否在加载类的时候,对字节码进行修改 我懵逼了,答曰不知道,面试官说可以的,使用Ja ...
- 【Mysql sql inject】【入门篇】sqli-labs使用 part 4【18-20】
这几关的注入点产生位置大多在HTTP头位置处 常见的HTTP注入点产生位置为[Referer].[X-Forwarded-For].[Cookie].[X-Real-IP].[Accept-Langu ...
- python 内置函数总结(大部分)
python 内置函数大讲堂 python全栈开发,内置函数 1. 内置函数 python的内置函数截止到python版本3.6.2,现在python一共为我们提供了68个内置函数.它们就是pytho ...
- __ATTR引发的编译错误【原创】
有一天我编译内核模块驱动的时候发现如下错误 Linux kernel版本:4.1.15 error: negative width in bit-field '<anonymous>' 代 ...
- 3D中的OBJ文件格式详解
常见到的*.obj文件有两种:第一种是基于COFF(Common Object File Format)格式的OBJ文件(也称目标文件),这种格式用于编译应用程序:第二种是Alias|Wavefron ...
- openstack常见问题解决方法总结
一.创建实例失败: 首先用下面命令查看服务是否正常 1. nova-manage service list 如果不正常,则使用下面命令重启,如果还不行,则查看日志, 1. service nova-a ...
- windows下设置计划任务自动执行PHP脚本
背景: 环境部署在linux下或者windows中,可以使用windows的自动任务设置自动执行脚本执行一些日常运维任务 图形界面设置相对比较简单 准备工作: wamp(集成的PHP执行环境) 已经写 ...
- nagios监控客户端报错/usr/bin/perl^M: bad interpreter: No such file or directory
nagios服务端监控客户端内存时发现监控不上 在客户端直接执行脚本,报错如下: # /usr/local/nagios/libexec/check_memory.pl -w 6% -c 3% -ba ...
- [java]用md5来判断两个文件是否完全相同
1. 前言 由于相比较两张图片是否是相同,如果通过像素点比较感觉速度比较慢,当很多图片进行比较时,效率就低很多了.由于每个文件md5基本上是唯一的,所以用获取文件的md5来判断是否相同文件. 2. 代 ...
- vue系列之核心思想
1.数据驱动 只要改变数据,Vuejs会通过Directives指令对DOM进行封装,当数据发生变化,会通知相应的DOM进行变化 Vuejs会对DOM进行监听,通过DOMListeners监听视图的变 ...