题目链接:洛谷

我们知道要求的是\([l_1,r_1],[l_2,r_2],[l_3,r_3]\)的可重集取交的大小,肯定是要用bitset的,那怎么做可重集呢?

那就是要稍微动点手脚,首先在离散化的时候,将\(a_x\)设为\(\leq a_x\)的数的个数,然后再插入一个数的时候,将\(a_x-cnt_{a_x}\)设为1,删除的时候设为0,然后直接取交就可以了。正确性比较显然。

还有一个问题就是如何存下\(100000*100000\)的bitset,那肯定是存不下的,所以把询问分成3部分,然后每块分别做就可以用时间换空间了。

#include<bits/stdc++.h>
#define Rint register int
using namespace std;
typedef long long LL;
const int N = 100010, M = 33340;
int n, m, _n, len, a[N], val[N], cnt[N], ql, qr, tmp[M];
bitset<N> ans[M], now;
struct Query {
int l, r, id;
inline bool operator < (const Query &o) const {
if(l / len != o.l / len) return l / len < o.l / len;
if(l / len & 1) return r > o.r;
return r < o.r;
}
} que[N];
inline void add(int x){++ cnt[x]; now[x - cnt[x]] = 1;}
inline void del(int x){now[x - cnt[x]] = 0; -- cnt[x];}
inline void solve(int m){
for(Rint i = 1;i <= n;i ++) cnt[i] = 0;
for(Rint i = 1;i <= m;i ++) ans[i].set(), tmp[i] = 0; now.reset(); ql = 1; qr = 0;
for(Rint i = 1;i <= 3 * m;i ++) scanf("%d%d", &que[i].l, &que[i].r), tmp[que[i].id = (i + 2) / 3] += que[i].r - que[i].l + 1;
sort(que + 1, que + 3 * m + 1);
for(Rint i = 1;i <= 3 * m;i ++){
while(ql > que[i].l) add(a[-- ql]);
while(qr < que[i].r) add(a[++ qr]);
while(qr > que[i].r) del(a[qr --]);
while(ql < que[i].l) del(a[ql ++]);
ans[que[i].id] &= now;
}
for(Rint i = 1;i <= m;i ++) printf("%d\n", tmp[i] - 3 * ans[i].count());
}
int main(){
scanf("%d%d", &n, &m); len = sqrt(n);
for(Rint i = 1;i <= n;i ++) scanf("%d", a + i), val[i] = a[i];
sort(val + 1, val + n + 1);
_n = unique(val + 1, val + n + 1) - val - 1;
for(Rint i = 1;i <= n;i ++) a[i] = lower_bound(val + 1, val + _n + 1, a[i]) - val;
for(Rint i = 1;i <= _n;i ++) val[i] = 0;
for(Rint i = 1;i <= n;i ++) ++ val[a[i]];
for(Rint i = 1;i <= _n;i ++) val[i] += val[i - 1];
for(Rint i = 1;i <= n;i ++) a[i] = val[a[i]];
solve(m / 3); solve((m + 1) / 3); solve((m + 2) / 3);
}

Luogu4688 [Ynoi2016]掉进兔子洞 【莫队,bitset】的更多相关文章

  1. [Luogu 4688] [Ynoi2016]掉进兔子洞 (莫队+bitset)

    [Luogu 4688] [Ynoi2016]掉进兔子洞 (莫队+bitset) 题面 一个长为 n 的序列 a.有 m 个询问,每次询问三个区间,把三个区间中同时出现的数一个一个删掉,问最后三个区间 ...

  2. BZOJ 4939: [Ynoi2016]掉进兔子洞(莫队+bitset)

    传送门 解题思路 刚开始想到了莫队+\(bitset\)去维护信息,结果发现空间不太够..试了各种奇技淫巧都\(MLE\),最后\(\%\)了发题解发现似乎可以分段做..这道题做法具体来说就是开\(3 ...

  3. BZOJ.4939.[Ynoi2016]掉进兔子洞(莫队 bitset 分组询问)

    BZOJ 洛谷 删掉的数即三个区间数的并,想到bitset:查多个区间的数,想到莫队. 考虑bitset的每一位如何对应每个数的不同出现次数.只要离散化后不去重,每次记录time就可以了. 但是如果对 ...

  4. BZOJ4939: [Ynoi2016]掉进兔子洞(莫队 bitset)

    题意 题目链接 一个长为 n 的序列 a. 有 m 个询问,每次询问三个区间,把三个区间中同时出现的数一个一个删掉,问最后三个区间剩下的数的个数和,询问独立. 注意这里删掉指的是一个一个删,不是把等于 ...

  5. 洛谷P4135 Ynoi2016 掉进兔子洞 (带权bitset?/bitset优化莫队 模板) 题解

    题面. 看到这道题,我第一反应就是莫队. 我甚至也猜出了把所有询问的三个区间压到一起处理然后分别计算对应询问答案. 但是,这么复杂的贡献用什么东西存?难道要开一个数组 query_appear_tim ...

  6. luogu P4688 [Ynoi2016]掉进兔子洞 bitset 莫队

    题目链接 luogu P4688 [Ynoi2016]掉进兔子洞 题解 莫队维护bitset区间交个数 代码 // luogu-judger-enable-o2 #include<cmath&g ...

  7. 【洛谷 P4688】 [Ynoi2016]掉进兔子洞(bitset,莫队)

    题目链接 第一道Ynoi 显然每次询问的答案为三个区间的长度和减去公共数字个数*3. 如果是公共数字种数的话就能用莫队+bitset存每个区间的状态,然后3个区间按位与就行了. 但现在是个数,bits ...

  8. bzoj千题计划320:bzoj4939: [Ynoi2016]掉进兔子洞(莫队 + bitset)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4939 ans= r1-l1+1 + r2-l2+1 +r3-l3+1 - ∑ min(cnt1[i ...

  9. BZOJ4939 Ynoi2016掉进兔子洞(莫队+bitset)

    容易发现要求三个区间各数出现次数的最小值.考虑bitset,不去重离散化后and一发就可以了.于是莫队求出每个区间的bitset.注意空间开不下,做多次即可.输出的东西错了都能调一年服了我了. #in ...

随机推荐

  1. BZOJ4400 TJOI2012桥(最短路+线段树)

    首先找出任意一条1-n的最短路径.显然删除的边只有在该最短路上才会对最短路长度产生影响. 不会证明地给出一个找不到反例的结论:删除一条边后,新图中一定有一条1-n的最短路径上存在一条边x->y, ...

  2. setTimeout()方法和setInterval()方法

    setTimeout方法: 定义和用法: setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. tip: 1000 毫秒= 1 秒. tip:  如果你只想重复执行可以使用setI ...

  3. web框架(1)-搭建开发环境

    一.python安装 首先,确认系统安装的Python版本 $ python3 -V Python 3.6.3 未安装python,请转至:python安装 二.安装第三方依赖库 1.异步框架aioh ...

  4. Hive数据库操作

    Hive数据结构 除了基本数据类型(与java类似),hive支持三种集合类型 Hive集合类型数据 array.map.structs hive (default)> create table ...

  5. Django之过滤器

    Django 过滤器   过滤器 描述 示例 upper 以大写方式输出 {{ user.name | upper }} add 给value加上一个数值 {{ user.age | add:”5” ...

  6. Linux 命令之 alias

    alias 的作用是为命令设置别名,用于提高输入效率 alias 的临时设置 临时设置很简单,直接举例说明 [r@1lin24 ~]$ alias cdlog='cd /var/log' [r@1li ...

  7. java - day013 - 流, FileInputStream, BufferedInputStream,

    流 Stream 把数据的读写,抽象成数据在管道中流动. 流是单向的 输入流, 只能用来读取数据 输出流, 只能用来输出数据 流只能顺序读写数据 流只能一次性从头到尾读写数据 流动过的数据,不能反复流 ...

  8. win10家庭版本不能连接远程桌面

    出现身份验证错误 要求的函数不受支持,CredSSP 加密 Oracle 修正 然后网上大多数教程是叫你修改组策略,然后试过坑的我发现自己的家庭版没有组策略,天真的我在网上找寻了装组策略的代码,一顿捣 ...

  9. 目录-java并发基础知识

    ====================== 1.volatile原理 2.ThreadLocal的实现原理(源码级) 3.线程池模型以及核心参数 4.HashMap的实现以及jdk8的改进(源码级) ...

  10. 蓝桥杯 ALGO-156 表达式计算 JAVA代码 栈的应用

     算法训练 表达式计算   时间限制:1.0s   内存限制:256.0MB      问题描述 输入一个只包含加减乖除和括号的合法表达式,求表达式的值.其中除表示整除. 输入格式 输入一行,包含一个 ...