题目链接:洛谷

我们知道要求的是\([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. PB笔记之第一行数据不能删除的解决方法

    如果第一行数据不能删除,则单独写SQL进行删除 window lw_sheet //dw_1.event pfc_deleterow()long i String ls_manidInteger ls ...

  2. FFplay源代码分析:整体流程图(仅供参考)

  3. (转)高效线程池之无锁化实现(Linux C)

    本文链接:https://blog.csdn.net/xhjcehust/article/details/45844901 笔者之前照着通用写法练手写过一个小的线程池版本,最近几天复习了一下,发现大多 ...

  4. 集合并卷积的三种求法(分治乘法,快速莫比乌斯变换(FMT),快速沃尔什变换(FWT))

    也许更好的阅读体验 本文主要内容是对武汉市第二中学吕凯风同学的论文<集合幂级数的性质与应用及其快速算法>的理解 定义 集合幂级数 为了更方便的研究集合的卷积,引入集合幂级数的概念 集合幂级 ...

  5. ionic开发遇到的问题总结

    前言 ionic是一个用来开发混合手机应用的,开源的,免费的代码库.可以优化html.css和js的性能,构建高效的应用程序,而且还可以用于构建Sass和AngularJS的优化.ionic会是一个可 ...

  6. Spring Cloud Alibaba学习笔记(5) - 整合Sentinel及Sentinel规则

    整合Sentinel 应用整合Sentinel 在dependencies中添加依赖,即可整合Sentinel <dependency> <groupId>com.alibab ...

  7. C#ModBus Tcp 报文解析

    上一篇博客已经完成 C#ModBus Tcp Master的实现 本篇主要对不同的功能码所发出的报文进行解析(包括请求报文及响应报文) 读操作 功能码 0x01 读一组线圈 读取站号为1 从地址12开 ...

  8. [转发]C++中new和malloc的区别

    原文地址:https://blog.csdn.net/linux_ever/article/details/50533149 new与malloc的10点区别 1. 申请的内存所在位置 new操作符从 ...

  9. git 丢弃本地代码

    git 丢弃本地代码 1.还未将变更加入到暂存区,即未执行git add 命令前可以使用git checkout 命令来撤销修改:git checkout -- rainbow.txt start.t ...

  10. 哈夫曼树详解——PHP代码实现

    在介绍哈夫曼树之前需要先了解一些专业术语 路径和路径长度 在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径.通路中分支的数目称为路径长度.若规定根结点的层数为1,则从根结点到第L ...