【bzoj3585】mex 线段树 mex,sg
Description
有一个长度为n的数组{a1,a2,…,an}。m次询问,每次询问一个区间内最小没有出现过的自然数。
Input
第一行n,m。
第二行为n个数。
从第三行开始,每行一个询问l,r。
Output
一行一个数,表示每个询问的答案。
Sample Input
2 1 0 2 1
3 3
2 3
2 4
1 2
3 5
Sample Output
2
3
0
3
HINT
数据规模和约定
对于100%的数据:
1<=n,m<=200000
0<=ai<=109
1<=l<=r<=n
对于30%的数据:
1<=n,m<=1000
离线瞎XX乱搞,只需要先处理出前缀的sg,表示最小没出现的自然数,然后就是
根据影响范围搞线段树即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring> #define inf 0x7fffffff
using namespace std;
inline int read()
{
int x=;char ch=getchar();
while(ch<''||ch>''){ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x;
} int n,m,cnt,k=;
int a[],b[],sg[],ans[],next[],last[];
int ls[],rs[],mn[];
bool mark[]; struct data{int l,r,id;}q[];
bool cmp(data a,data b)
{return a.l<b.l;}
int find(int x)
{
int l=,r=cnt;
while(l<=r)
{
int mid=(l+r)>>;
if(b[mid]<x)l=mid+;
else r=mid-;
}
return l;
}
void build(int k,int l,int r)
{
ls[k]=l;rs[k]=r;mn[k]=inf;
if(l==r){mn[k]=sg[l];return;}
int mid=(l+r)>>;
build(k<<,l,mid);build(k<<|,mid+,r);
}
void pushdown(int k)
{
int l=ls[k],r=rs[k];
if(l==r)return;
mn[k<<]=min(mn[k],mn[k<<]);
mn[k<<|]=min(mn[k],mn[k<<|]);
}
int ask(int k,int x)
{
if(mn[k]!=inf)pushdown(k);
int l=ls[k],r=rs[k];
if(l==r)return mn[k];
int mid=(l+r)>>;
if(x<=mid)return ask(k<<,x);
return ask(k<<|,x);
}
void update(int k,int x,int y,int val)
{
if(mn[k]!=inf)pushdown(k);
int l=ls[k],r=rs[k];
if(l==x&&y==r){mn[k]=min(mn[k],val);return;}
int mid=(l+r)>>;
if(y<=mid)update(k<<,x,y,val);
else if(x>mid)update(k<<|,x,y,val);
else {update(k<<,x,mid,val);update(k<<|,mid+,y,val);}
}
int main()
{
n=read(),m=read();
for(int i=;i<=n;i++)
a[i]=b[i]=read();
sort(b+,b+n+);
for(int i=;i<=n;i++)
if(b[i]!=b[i-]||i==)b[++cnt]=b[i];
for(int i=;i<=n;i++)
{
int t=find(a[i]);
mark[t]=;
if(a[i]==k)
while(mark[t])
{
k++;
if(b[++t]!=k)break;
}
sg[i]=k;
}
build(,,n);
for(int i=n;i>;i--)
next[i]=last[find(a[i])],last[find(a[i])]=i;
/*for (int i=1;i<=n;i++)
cout<<next[i]<<" ";
cout<<endl;
for (int i=1;i<=n;i++)
cout<<last[i]<<" ";
cout<<endl;*/
for(int i=;i<=m;i++)
{
q[i].l=read();q[i].r=read();
q[i].id=i;
}
sort(q+,q+m+,cmp);
int now=;
for(int i=;i<=m;i++)
{
while(now<q[i].l)
{
if(!next[now])next[now]=n+;
update(,now,next[now]-,a[now]);
now++;
}
ans[q[i].id]=ask(,q[i].r);
}
for(int i=;i<=m;i++)
printf("%d\n",ans[i]);
}
【bzoj3585】mex 线段树 mex,sg的更多相关文章
- HDU-4747 Mex 线段树
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747 题意:求一个数列中,所有mex(L,R)的和. 注意到mex是单调不降的,那么首先预处理出mex ...
- [置顶] hdu4747 Mex 线段树
题意:给你一个序列,让你求出对于所有区间<i, j>的mex和,mex表示该区间没有出现过的最小的整数. 思路:从时限和点数就可以看出是线段树,并且我们可以枚举左端点i, 然后求出所有左端 ...
- BZOJ.3585.mex(线段树)
题目链接 题意:多次求区间\(mex\). 考虑\([1,i]\)的\(mex[i]\),显然是单调的 而对于\([l,r]\)与\([l+1,r]\),如果\(nxt[a[l]]>r\),那么 ...
- hdu 4747 mex 线段树+思维
http://acm.hdu.edu.cn/showproblem.php?pid=4747 题意: 我们定义mex(l,r)表示一个序列a[l]....a[r]中没有出现过得最小的非负整数, 然后我 ...
- bzoj 3585 mex - 线段树 - 分块 - 莫队算法
Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问 ...
- BZOJ 3339 Rmq Problem(离线+线段树+mex函数)
题意: q次询问,问[l,r]子区间的mex值 思路: 对子区间[l,r],当l固定的时候,[l,r]的mex值对r单调不减 对询问按照l离线,对当前的l,都有维护一个线段树,每个叶节点保存[l,r] ...
- Codeforces 1083C Max Mex [线段树]
洛谷 Codeforces 思路 很容易发现答案满足单调性,可以二分答案. 接下来询问就转换成判断前缀点集是否能组成一条链. 我最初的想法:找到点集的直径,判断直径是否覆盖了所有点,需要用到树套树,复 ...
- [bzoj3339]Rmq Problem||[bzoj3585]mex_线段树
Rmq Problem bzoj-3339||mex bzoj-3585 题目大意:给定一个长度为n的数列a,多次讯问区间l,r中最小的不属于集合{$A_l,A_{l+1}...A_r$}的非负整数. ...
- CF1083C Max Mex 线段树
题面 CF1083C Max Mex 题解 首先我们考虑,如果一个数x是某条路径上的mex,那么这个数要满足什么条件? 1 ~ x - 1的数都必须出现过. x必须没出现过. 现在我们要最大化x,那么 ...
随机推荐
- 更新MySQL数据库( java.sql.SQLException: No value specified for parameter 1) 异常 解决方法
package com.swift; import java.io.File; import java.sql.Connection; import java.sql.PreparedStatemen ...
- es6中的模版字符串
目录 字符串拼接 includes() startsWith() endsWith() padStart() es6中的模版字符串替代了原有的字符串拼接功能. 字符串拼接 es5方式 传统的字符串拼接 ...
- 第26题:LeetCode572:Subtree of Another Tree另一个树的子树
题目描述 给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树.s 的一个子树包括 s 的一个节点和这个节点的所有子孙.s 也可以看做它自身的一棵子树. 示例 1: ...
- 51nod——2487小b和环
dp[ i ][ 0 ] : 第i个位置不取 dp[ i ][ 1 ] : 第i个位置取 这样就可以得到状态转移方程: dp[i][0]=max(max(dp[i][0],dp[i-1][1]),dp ...
- 自动化运维工具——ansible命令使用(二)
一.Ansible系列命令使用 ansible命令执行过程 1 . 加载自己的配置文件 默认/etc/ansible/ansible.cfg 2 . 加载自己对应的模块文件,如command 3 . ...
- 安全 - 堡垒机 - Jumpserver
GitHub - jumpserver/Dockerfile: Jumpserver all in one Dockerfile https://github.com/jumpserver/Docke ...
- Python猫荐书系列之七:Python入门书籍有哪些?
本文原创并首发于公众号[Python猫],未经授权,请勿转载. 原文地址:https://mp.weixin.qq.com/s/ArN-6mLPzPT8Zoq0Na_tsg 最近,猫哥的 Python ...
- Oracle两种临时表的创建与使用详解
ORACLE数据库除了可以保存永久表外,还可以建立临时表temporary tables.这些临时表用来保存一个会话SESSION的数据,或者保存在一个事务中需要的数据.当会话退出或者用户提交comm ...
- C++构造函数使用的多种方法
// classes and uniform initialization #include <iostream> using namespace std; class Circle { ...
- 从0到n-1中随机等概率输出m个不同的数
//假设输入的n远大于m void knuth(int n, int m) { for (int i = 0; i < n; i++) { if (rand() % (n - i)<m) ...