BZOJ - 3339: Rmq BZOJ - 3585: mex

3339: Rmq Problem

3585: mex

题解:分块维护权值,用莫队转移。

分块修改操作$O(1)$,查询$O(\sqrt{A_{max}})$。莫队转移$O(m\sqrt n)$。总共是$O(m\sqrt n)$

一份代码解决两道题。额外的经验!

 1 #include<cmath>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<iostream>
 5 using namespace std;
 6 inline char nc() {
 7     static char b[1<<14],*s=b,*t=b;
 8     return s==t&&(t=(s=b)+fread(b,1,1<<14,stdin),s==t)?-1:*s++;
 9 }
10 inline void read(int &x) {
11     char b = nc(); x = 0;
12     for (; !isdigit(b); b = nc());
13     for (; isdigit(b); b = nc()) x = x * 10 + b - ‘0‘;
14 }
15 int n, m, a[200010], ans[200010];
16 int S, bl[200010], tans, cnt[200010];
17 struct Q {
18     int l, r, id, t;
19     inline void init(int i) {
20         read(l); read(r); id = i; t = l / S;
21     }
22     inline bool operator<(const Q &q) const {
23         return t < q.t || (t == q.t && r < q.r);
24     }
25 } q[200010];
26 const int INF = 0x3f3f3f3f;
27 void edt(int x, int k) {
28     if (x > n) return; cnt[x] += k;
29     if (x < tans && !cnt[x]) tans = x;
30     while (cnt[tans]) ++tans;
31 }
32 int main() {
33     read(n); read(m); S = sqrt(n);
34     for (int i = 1; i <= n; ++i) read(a[i]);
35     for (int i = 0; i <= n; ++i) bl[i] = i / S + 1;
36     for (int i = 0; i < m; ++i) q[i].init(i);
37     sort(q, q + m); edt(a[1], 1);
38     for (int l = 1, r = 1, i = 0; i < m; ++i) {
39         while (l < q[i].l) edt(a[l++], -1);
40         while (l > q[i].l) edt(a[--l], 1);
41         while (r < q[i].r) edt(a[++r], 1);
42         while (r > q[i].r) edt(a[r--], -1);
43         ans[q[i].id] = tans;
44     }
45     for (int i = 0; i < m; ++i) printf("%d\n", ans[i]);
46     return 0;
47 }

原文地址:https://www.cnblogs.com/p0ny/p/8127849.html

时间: 2024-10-27 10:11:56

BZOJ - 3339: Rmq BZOJ - 3585: mex的相关文章

【BZOJ】3339: Rmq Problem &amp; 3585: mex(线段树+特殊的技巧)

http://www.lydsy.com/JudgeOnline/problem.php?id=3585 好神的题. 但是!!!!!!!!!!!!!!我线段树现在要开8倍空间才能过!!!!!!!!!!这什么梗...................... 我思考了很久空间的问题,因为我在pushdown的时候可能会越界,或许是pushup? 不管了.然后看了zyf的写法.看来以后得注意下...pushdown弄成先放了... 本题的做法: 好神orz 首先像莫队一样离线区间,左端点在前. 考虑如何

bzoj 3339: Rmq Problem

3339: Rmq Problem Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1270  Solved: 666[Submit][Status][Discuss] Description Input Output Sample Input 7 5 0 2 1 0 1 3 2 1 3 2 3 1 4 3 6 2 7 Sample Output 3 0 3 2 4 HINT Source By Xhr 嗯,莫队 懒得敲线段树,毕竟线段树比较短 #

bzoj 3585: mex &amp;&amp; 3339: Rmq Problem -- 主席树

3585: mex Time Limit: 20 Sec  Memory Limit: 128 MB Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问l,r. Output 一行一个数,表示每个询问的答案. Sample Input 5 5 2 1 0 2 1 3 3 2 3 2 4 1 2 3 5 Sample Output 1 2 3 0 3

bzoj 3585: mex

3585: mex Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 969  Solved: 511[Submit][Status][Discuss] Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问l,r. Output 一行一个数,表示每个询问的答案. Sample Input 5 5 2 1

[BZOJ 3585] mex 【莫队+分块】

题目链接:BZOJ - 3585 题目分析 区间mex,即区间中没有出现的最小自然数. 那么我们使用一种莫队+分块的做法,使用莫队维护当前区间的每个数字的出现次数. 然后求mex用分块,将权值分块(显然mex 一定小于等于 n ,大于 n 的权值没有意义,可以直接忽略),每块大小 sqrt(n) . 然后区间中的某个数的数量被减到0的时候就将它所在的块的种类计数减一,添加数的时候类似. 然后枚举每个块,找到最小的中间有数不存在的块(即种类数小于块中的数的种数),然后到这个快里直接从小一个一个找到

AC日记——Rmq Problem bzoj 3339

3339 思路: 恶心: 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 200005 struct TreeNodeType { int l,r,dis,mid,flag; bool if_; }; struct TreeNodeType tree[maxn<<2

BZOJ 3585 mex 莫队算法+分块

题目大意:给定一个长度为n的数组,m次询问某个区间内的mex值 怒写莫队233 将权值分成√n块,记录每个权值的出现次数以及每块内有多少权值出现过 修改O(1)即可完成 查询时首先扫一遍找到第一个块内有没有覆盖的点的块 然后在块内暴力查找 时间复杂度O(√n) 套个莫队 总时间复杂度O(m√n) #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include

BZOJ.3585.mex(线段树)

题目链接 考虑\([1,i]\)的\(mex[i]\),显然是单调的 而对于\([l,r]\)与\([l+1,r]\),如果\(nxt[a[l]]>r\),那么\([l+1,r]\)中所有\(>a[l]\)的数显然要改成\(a[l]\) 询问排序,离散化,预处理下nxt[],剩下就是线段树的区间更新.查询了 /* 离散化的时候>=n的全部看做n就好了 查询时是只需查r点的(l之前能更新r的已经更新完了,初始时是[1,r],r点现在就是[l,r]了) 单点即可不需要PushUp(也不好得某

BZOJ 3339 &amp;&amp; BZOJ 3585 莫队+权值分块

显然若一个数大于n就不可能是答案. 1 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <algorithm> 6 #include <map> 7 #include <cmath> 8 using namespace std; 9 const int Maxn=200010; 10 struct Info{int l,r,Id;}P[