bzoj 3585 mex - 线段树 - 分块 - 莫队算法
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
Source
题目大意
区间询问mex。
Solution 1 Mo's Algorithm & Block Division
区间求mex?不会,直接莫队。
由于一个数大于等于$n$时无意义,所以按$n$分块,每块记录是否完全被覆盖。
查询时暴力跳。
表示数据真水,最开始某个地方的$x$,写成$p$竟然A了。
Code
/**
* bzoj
* Problem#3585
* Accepted
* Time: 6832ms
* Memory: 5988k
*/
#include <bits/stdc++.h>
using namespace std;
typedef bool boolean; const int cs = ; typedef class Query {
public:
int l, r;
int id; Query() { } boolean operator < (Query b) const {
if (l / cs != b.l / cs) return l < b.l;
return r < b.r;
}
}Query; int n, m;
int* ar;
Query* qs;
int exist[];
int cover[cs];
int *res; inline void init() {
scanf("%d%d", &n, &m);
ar = new int[(n + )];
qs = new Query[(m + )];
res = new int[(m + )];
for (int i = ; i <= n; i++)
scanf("%d", ar + i);
for (int i = ; i <= m; i++)
scanf("%d%d", &qs[i].l, &qs[i].r), qs[i].id = i;
} inline void update(int p, int sign) {
int x = ar[p];
if (x >= n) return;
if (!exist[x] && sign == ) cover[x / cs]++;
exist[x] += sign;
if (!exist[x] && sign == -)cover[x / cs]--;
} inline void solve() {
sort(qs + , qs + m + );
int mdzzl = , mdzzr = ;
for (int i = ; i <= m; i++) {
while (mdzzr < qs[i].r) update(++mdzzr, );
while (mdzzr > qs[i].r) update(mdzzr--, -);
while (mdzzl < qs[i].l) update(mdzzl++, -);
while (mdzzl > qs[i].l) update(--mdzzl, ); for (int j = ; j < cs; j++) {
if (cover[j] < cs) {
int k = j * cs;
while (exist[k]) k++;
res[qs[i].id] = k;
break;
}
}
} for (int i = ; i <= m; i++)
printf("%d\n", res[i]);
} int main() {
init();
solve();
return ;
}
分块&莫队
Solution 2 Segment Tree
假设你通过某种方式求出了$[1, i]$的答案。
考虑删掉位置1,那么位置上的数到下一次它出现之前都可以用来更新答案。
于是线段树区间修改,单点查询,做完了。
Code
/**
* bzoj
* Problem#3585
* Accepted
* Time: 4436ms
* Memory: 15184k
*/
#include <bits/stdc++.h>
using namespace std;
typedef bool boolean; #define smin(_a, _b) (_a > _b) ? (_a = _b) : (0) typedef class Query {
public:
int l, r, id, next;
}Query; typedef class SegTreeNode {
public:
int val;
SegTreeNode *l, *r; SegTreeNode():l(NULL), r(NULL) { }
}SegTreeNode; SegTreeNode pool[];
SegTreeNode* top = pool; SegTreeNode* newnode(int val) {
top->val = val;
return top++;
} typedef class SegTree {
public:
SegTreeNode* rt; SegTree() { }
SegTree(int n, int* f) {
build(rt, , n, f);
} void build(SegTreeNode*& p, int l, int r, int* f) {
p = newnode();
if (l == r) {
p->val = f[l];
return;
}
int mid = (l + r) >> ;
build(p->l, l, mid, f);
build(p->r, mid + , r, f);
} void update(SegTreeNode* p, int l, int r, int ql, int qr, int val) {
if (l == ql && r == qr) {
smin(p->val, val);
return;
}
int mid = (l + r) >> ;
if (qr <= mid)
update(p->l, l, mid, ql, qr, val);
else if (ql > mid)
update(p->r, mid + , r, ql, qr, val);
else {
update(p->l, l, mid, ql, mid, val);
update(p->r, mid + , r, mid + , qr, val);
}
} int query(SegTreeNode* p, int l, int r, int idx) {
if (l == idx && r == idx)
return p->val;
int mid = (l + r) >> , rt = p->val, a = ;
if (idx <= mid)
a = query(p->l, l, mid, idx);
else
a = query(p->r, mid + , r, idx);
return (a < rt) ? (a) : (rt);
}
}SegTree; int n, m;
int *ar, *suf;
int *last, *res;
Query *qs;
int *h, *f;
SegTree st;
boolean *exist; inline void init() {
scanf("%d%d", &n, &m);
h = new int[(n + )];
f = new int[(n + )];
ar = new int[(n + )];
suf = new int[(n + )];
res = new int[(m + )];
qs = new Query[(m + )];
last = new int[(n + )];
exist = new boolean[(n + )];
fill(h, h + n + , );
fill(suf, suf + n + , n + );
fill(last, last + n + , );
fill(exist, exist + n + , false);
for (int i = , x; i <= n; i++) {
scanf("%d", ar + i);
if (ar[i] >= n) continue;
x = ar[i];
if (last[x])
suf[last[x]] = i;
last[x] = i;
}
for (int i = ; i <= m; i++) {
scanf("%d%d", &qs[i].l, &qs[i].r);
qs[i].id = i, qs[i].next = h[qs[i].l], h[qs[i].l] = i;
}
} inline void prepare() {
int p = ;
for (int i = ; i <= n; i++) {
if (ar[i] < n)
exist[ar[i]] = true;
while (exist[p]) p++;
f[i] = p;
}
st = SegTree(n, f);
} inline void solve() {
for (int i = ; i <= n; i++) {
for (int j = h[i]; j; j = qs[j].next)
res[qs[j].id] = st.query(st.rt, , n, qs[j].r);
if (ar[i] < n) {
st.update(st.rt, , n, i, suf[i] - , ar[i]);
}
}
for (int i = ; i <= m; i++)
printf("%d\n", res[i]);
} int main() {
init();
prepare();
solve();
return ;
}
bzoj 3585 mex - 线段树 - 分块 - 莫队算法的更多相关文章
- BZOJ.3585.mex(线段树)
题目链接 题意:多次求区间\(mex\). 考虑\([1,i]\)的\(mex[i]\),显然是单调的 而对于\([l,r]\)与\([l+1,r]\),如果\(nxt[a[l]]>r\),那么 ...
- BZOJ 1878 [SDOI2009]HH的项链 (主席树 或 莫队算法)
题目链接 HH的项链 这道题可以直接上主席树的模板 #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) ...
- 【BZOJ-3809】Gty的二逼妹子序列 分块 + 莫队算法
3809: Gty的二逼妹子序列 Time Limit: 80 Sec Memory Limit: 28 MBSubmit: 1072 Solved: 292[Submit][Status][Di ...
- bzoj 2038 A-小Z的袜子[hose] - 莫队算法
作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… 具体来说,小Z把这N只袜子从1到N编号,然后从 ...
- bzoj 3289 Mato的文件管理(莫队算法+BIT)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3289 [题意] 回答若干个询问:[l,r]区间内的逆序对个数. [思路] 莫队算法,B ...
- bzoj 2308 小Z的袜子(莫队算法)
小Z的袜子 [题目链接]小Z的袜子 [题目类型]莫队算法 &题解: 莫队算法第一题吧,建议先看这个理解算法,之后在参考这个就可以写出简洁的代码 我的比第2个少了一次sort,他的跑了1600m ...
- bzoj 2038 小Z的袜子 莫队算法
题意 给你一个长度序列,有多组询问,每次询问(l,r)任选两个数相同的概率.n <= 50000,数小于等于n. 莫队算法裸题. 莫队算法:将序列分为根号n段,将询问排序,以L所在的块为第一关键 ...
- 主席树||可持久化线段树+离散化 || 莫队+分块 ||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 [主席树]
3585: mex Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 787 Solved: 422[Submit][Status][Discuss] ...
随机推荐
- 2019 创蓝253java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.创蓝253等公司offer,岗位是Java后端开发,因为发展原因最终选择去了创蓝253,入职一年时间了,也成为 ...
- Django--母版
目录 母版 语法 案例 在之前的两个小程序中,可以发现在写html页面的时候有很多重复的代码 而在python中,为了避免写重复代码,我们通过函数.模块或者类来进行实现,所以在Django里面也有这样 ...
- js计算得来的属性
计算得来的属性 如果需要使用表达式来创建属性键,那么需要使用方括号.否则属性名称不会进行计算: var obj = { 'b'+'ar': 'foo' }; // SyntaxError: missi ...
- JavaSE01:初始Java
java语言的优势 简单性 面向对象 跨平台性(可移植性) 高性能 分布式 动态性 多线程 安全性 健壮性 java最大的特点是跨平台性 Java的跨平台性来源于Java虚拟机(jvm),Java靠在 ...
- 总结HTML5新增的标签及功能
https://my.oschina.net/chengkuan/blog/422306 标记意义及用法分析/示例 属性/属性值/描述 <article> 定义独立的内容,如论坛帖子.报纸 ...
- SAP技术 - How to create a CDS redirect view for a given database table
Scenario Suppose we have a database table A, and then we create a CDS redirect view B for it, then e ...
- Docker08-网络管理
目录 桥接网络 Bridge Network 相关操作命令 实例演示:容器之间通过自定义bridge通讯 宿主网络 Host Network Overlay Network 相关操作命令 实例演示:容 ...
- 个人推荐的Java邮件配置
# 大部分host都是smtp.加上你邮箱@后面的域名spring.mail.host=smtp.localhost.com spring.mail.username= spring.mail.pas ...
- Tensorflow简单实践系列(三):图和会话
当执行一个 TensorFlow 函数的时候,并不会马上执行运算,而是把运算存储到一个称为“图”(graph)的数据结构里面. 图存储的各种运算,只有在会话(session)里执行图,才会真正地执行. ...
- 关于Discuz x3.3页面空白解决方法
今天找时间分析了一下,找到了页面空白的原因,可能是因为php版本兼容性的问题所致,所以只是部分用户遇到这种情况,这里分享一下.经过分析发现是sourcefunctionfunction_core.ph ...