题目链接:BZOJ - 3585

题目分析

区间mex,即区间中没有出现的最小自然数。

那么我们使用一种莫队+分块的做法,使用莫队维护当前区间的每个数字的出现次数。

然后求mex用分块,将权值分块(显然mex 一定小于等于 n ,大于 n 的权值没有意义,可以直接忽略),每块大小 sqrt(n) 。

然后区间中的某个数的数量被减到0的时候就将它所在的块的种类计数减一,添加数的时候类似。

然后枚举每个块,找到最小的中间有数不存在的块(即种类数小于块中的数的种数),然后到这个快里直接从小一个一个找到第一个不存在的数。

这样莫队的复杂度和分块的复杂度是相加的, O(n^1.5) + O(n^1.5) = O(n^1.5) 。

代码

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm> using namespace std; const int MaxN = 200000 + 5, MaxQ = 200000 + 5, MaxB = 500 + 5; int n, m, BlkSize, MaxBlk;
int A[MaxN], Blk[MaxN], L[MaxB], R[MaxB], Ans[MaxQ], Cnt[MaxN], V[MaxB], Size[MaxB]; struct Query
{
int Idx, l, r, v;
} Q[MaxQ]; inline bool Cmp(Query q1, Query q2)
{
if (q1.v == q2.v) return q1.r < q2.r;
return q1.v < q2.v;
} inline void Del_Num(int x)
{
--Cnt[x];
if (Cnt[x] == 0) --V[Blk[x]];
} inline void Add_Num(int x)
{
if (Cnt[x] == 0) ++V[Blk[x]];
++Cnt[x];
} void Pull(int f, int x, int y)
{
if (x == y) return;
if (f == 0)
{
if (x < y)
{
for (int i = x; i < y; ++i)
Del_Num(A[i]);
}
else
{
for (int i = x - 1; i >= y; --i)
Add_Num(A[i]);
}
}
else
{
if (x < y)
{
for (int i = x + 1; i <= y; ++i)
Add_Num(A[i]);
}
else
{
for (int i = x; i > y; --i)
Del_Num(A[i]);
}
}
} int Get_Ans()
{
int ret = n;
for (int i = 1; i <= MaxBlk; ++i)
if (V[i] < Size[i])
{
for (int j = L[i]; j <= R[i]; ++j)
if (Cnt[j] == 0)
{
ret = j;
break;
}
break;
}
return ret;
} int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)
{
scanf("%d", &A[i]);
if (A[i] > n) A[i] = n + 1;
}
BlkSize = (int)sqrt((double)n);
for (int i = 0; i <= n; ++i) Blk[i] = i / BlkSize + 1;
MaxBlk = Blk[n];
for (int i = 1; i <= MaxBlk; ++i)
{
L[i] = (i - 1) * BlkSize;
R[i] = i * BlkSize - 1;
Size[i] = R[i] - L[i] + 1;
}
R[MaxBlk] = n;
Size[MaxBlk] = n - L[MaxBlk] + 1;
for (int i = 1; i <= m; ++i)
{
scanf("%d%d", &Q[i].l, &Q[i].r);
Q[i].Idx = i;
Q[i].v = Q[i].l / BlkSize;
}
sort(Q + 1, Q + m + 1, Cmp);
for (int i = Q[1].l; i <= Q[1].r; ++i) Add_Num(A[i]);
Ans[Q[1].Idx] = Get_Ans();
for (int i = 2; i <= m; ++i)
{
if (Q[i].r <= Q[i - 1].l)
{
Pull(0, Q[i - 1].l, Q[i].l);
Pull(1, Q[i - 1].r, Q[i].r);
}
else
{
Pull(1, Q[i - 1].r, Q[i].r);
Pull(0, Q[i - 1].l, Q[i].l);
}
Ans[Q[i].Idx] = Get_Ans();
}
for (int i = 1; i <= m; ++i) printf("%d\n", Ans[i]);
return 0;
}

  

[BZOJ 3585] mex 【莫队+分块】的更多相关文章

  1. Bzoj 3339: Rmq Problem && Bzoj 3585: mex 莫队,树状数组,二分

    3339: Rmq Problem Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 833  Solved: 397[Submit][Status][D ...

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

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

  3. bzoj 3585 mex - 线段树 - 分块 - 莫队算法

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

  4. 【BZOJ3339&&3585】mex [莫队][分块]

    mex Time Limit: 20 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 有一个长度为n的数组{a1,a2,. ...

  5. [BZOJ 3236] [Ahoi2013] 作业 && [BZOJ 3809] 【莫队(+分块)】

    题目链接: BZOJ - 3236   BZOJ - 3809 算法一:莫队 首先,单纯的莫队算法是很好想的,就是用普通的第一关键字为 l 所在块,第二关键字为 r 的莫队. 这样每次端点移动添加或删 ...

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

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

  7. Bzoj 3236: [Ahoi2013]作业 莫队,分块

    3236: [Ahoi2013]作业 Time Limit: 100 Sec  Memory Limit: 512 MBSubmit: 1113  Solved: 428[Submit][Status ...

  8. 莫队+分块 BZOJ 3809

    3809: Gty的二逼妹子序列 Time Limit: 80 Sec  Memory Limit: 28 MBSubmit: 1634  Solved: 482[Submit][Status][Di ...

  9. BZOJ_3585_mex && BZOJ_3339_Rmq Problem_莫队+分块

    BZOJ_3585_mex && BZOJ_3339_Rmq Problem_莫队+分块 Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一 ...

随机推荐

  1. VS2015+TFS2015源代码管理

    使用Visual Studio连接TFS

  2. jQuery滑动并响应事件

    jQuery滑动并打开指定页面: <!DOCTYPE html> <html> <head> <script src="http://code.jq ...

  3. Linq扩展方法之Aggregate 对序列应用累加器函数

    Linq扩展方法之Aggregate  对序列应用累加器函数; 函数模板:// 函数名:对序列应用累加器函数. // Parameters:参数要求 // source:要聚合的 System.Col ...

  4. python 简明教程笔记

    1,python特点 python 注重的是如何解决问题,而不是语法和结构简单高效.扩展性 2,安装 python python -V        检测是否安装pythonctrl+d       ...

  5. [序列化] Serialize--序列化帮助类 (转载)

    点击下载 Serialize.zip 这个类是关于加密,解密的操作,文件的一些高级操作1.序列化2.要序列化的类3.序列化例子看下面代码吧 /// <summary> /// 类说明:As ...

  6. [XML] Resource帮助类

    点击下载 Resources.rar /// <summary> /// 类说明:Resources /// 编 码 人:苏飞 /// 联系方式:361983679 /// 更新网站:[u ...

  7. Javascript基础学习(2)_表达式和运算符

    1.==和===的区别(!=和!==是相反的比较) 它们采用了同一性的两个不同定义.==是相等性,===是等同性. ①“===”进行两个值的比较 两个值的类型不同,就不相等 两个值是数字,并且值相同, ...

  8. jquery和js cookie的使用解析

    JavaScript是运行在客户端的脚本,因此一般是不能够设置Session的,因为Session是运行在服务器端的.而cookie是运行在客户端的,所以可以用JS来设置cookie. 在这里分别通过 ...

  9. 读书笔记之 - javascript 设计模式 - 观察者模式

    在事件驱动的环境中,比如浏览器这种持续寻求用户关注的环境中,观察者模式是一种管理人与其任务(确切的讲,是对象及其行为和状态之间的关系)之间的关系的得力工具.用javascript的话来讲,这种模式的实 ...

  10. MVVM模式应用 之xml文件的读取

    XML如下所示: <?xml version="1.0" encoding="utf-8" ?> <schools> <schoo ...