题面:http://www.lydsy.com/JudgeOnline/problem.php?id=4939


大意:
每个询问有三个区间。将三个区间里都出现的数字一个一个地删除,直到不能操作为止,求这时三个区间里总共还剩下多少个数字。

稍微思考一下发现就是求∑3i=1(ri−li+1)−3∑109i=0min{cnt1i,cnt2i,cnt3i}∑i=13(ri−li+1)−3∑i=0109min{cnt1i,cnt2i,cnt3i}\sum_{i=1}^3(r_i-l_i+1)- 3\sum_{i=0}^{10^9}min\{cnt_{1i},cnt_{2i},cnt_{3i} \},其中cntijcntijcnt_{ij}为第i个区间里数字j的出现次数。

显然要先离散化。考虑离散化之后如何处理。发现用什么数据结构都不好处理,而这又是一个关于区间的问题,所以考虑把每个询问拆成三个区间,使用莫队算法。然而发现虽然我们很容易通过莫队维护cntijcntijcnt_{ij},但是后面的求和却不好维护。这里正解是压位。

由于bitset每一位上的值只有0/1两种,不能直接维护cntijcntijcnt_{ij},考虑更特殊的情况。如果aiaia_i的值两两不同,那么cntijcntijcnt_{ij}就只有0/1两种取值,这时候就能够用bitset维护每个数字在区间内是否出现过,∑109i=0min{cnt1i,cnt2i,cnt3i}∑i=0109min{cnt1i,cnt2i,cnt3i}\sum_{i=0}^{10^9}min\{cnt_{1i},cnt_{2i},cnt_{3i} \}就是三个区间的bitset取交后1的位置个数。

考虑处理aiaia_i不必两两相同的情况。拿样例来说:

5 2
1 2 2 3 3
1 2 2 3 3 4
1 5 1 5 1 5

1 2 2 3 3离散化之后是1 2 2 4 4。那么离散化之后,将bitset里第一位表示1是否出现过,第二位表示第一个2是否出现过,第三位表示第二个2是否出现过,第四位表示第一个4是否出现过,第五位表示第二个4是否出现过。这样处理之后,发现就能够以相同的方式计算∑109i=0min{cnt1i,cnt2i,cnt3i}∑i=0109min{cnt1i,cnt2i,cnt3i}\sum_{i=0}^{10^9}min\{cnt_{1i},cnt_{2i},cnt_{3i} \}了。

注意到直接对所有询问用莫队处理会MLE,那么把询问可以分成几块分别处理,以重复利用空间。


代码:

#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<bitset>
#include<cmath>
#define MAXN 100005
using namespace std;int N,M,Be[MAXN],A[MAXN],Hash[MAXN],Ans[MAXN];struct seg{int l,r,id;
}Q[MAXN*3];struct node{int l1,r1,l2,r2,l3,r3;
}data[MAXN];bool operator<(seg a,seg b){if(Be[a.l]==Be[b.l])return a.r<b.r;return Be[a.l]<Be[b.l];
}bitset<MAXN>Tmp,f[25005];
int Cnt[MAXN];
bool vis[25005];void Update(int p,int k){p=A[p];Cnt[p]+=k;if(k==1)Tmp[p+Cnt[p]-2]=1;else Tmp[p+Cnt[p]-1]=0;
}void Solve(int l,int r){int i,tot=0;for(i=l;i<=r;i++){Q[++tot]=(seg){data[i].l1,data[i].r1,i};Q[++tot]=(seg){data[i].l2,data[i].r2,i};Q[++tot]=(seg){data[i].l3,data[i].r3,i};}sort(Q+1,Q+tot+1);int L=1,R=0;Tmp.reset();memset(vis,0,sizeof(vis));memset(Cnt,0,sizeof(Cnt));for(i=1;i<=tot;i++){while(R<Q[i].r)Update(++R,1);while(R>Q[i].r)Update(R--,-1);while(L<Q[i].l)Update(L++,-1);while(L>Q[i].l)Update(--L,1);if(vis[Q[i].id-l])f[Q[i].id-l]&=Tmp;else f[Q[i].id-l]=Tmp,vis[Q[i].id-l]=1;}for(i=l;i<=r;i++)Ans[i]-=f[i-l].count()*3;
}int main(){int i,j;scanf("%d%d",&N,&M);for(i=1;i<=N;i++){scanf("%d",&A[i]);Hash[i]=A[i];}sort(Hash+1,Hash+N+1);for(i=1;i<=N;i++)A[i]=lower_bound(Hash+1,Hash+N+1,A[i])-Hash;int S=sqrt(N);for(i=j=1;i<=N;i++){Be[i]=j;if(i%S==0)j++;}for(i=1;i<=M;i++){int l1,r1,l2,r2,l3,r3;scanf("%d%d%d%d%d%d",&l1,&r1,&l2,&r2,&l3,&r3);Ans[i]+=r1-l1+r2-l2+r3-l3+3;data[i]=(node){l1,r1,l2,r2,l3,r3};}Solve(1,min(25000,M));if(M>25000)Solve(25001,min(50000,M));if(M>50000)Solve(50001,min(75000,M));if(M>75000)Solve(75001,M);//对询问分块处理for(i=1;i<=M;i++)printf("%d\n",Ans[i]);
}

4939: [Ynoi2016]掉进兔子洞 莫队 压位相关推荐

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

    题目链接 BZOJ 洛谷 扯点别的 听说这是比较亲民的一道Ynoi,于是我就去摸了一下,于是一个晚上就没了--不过至少还是学到了\(bitset\)维护可重集合的方法,以及当空间开不下时分组处理询问的 ...

  2. BZOJ4939 [YNOI2016]掉进兔子洞

    题目蓝链 Solution 首先,很显然这题是要用莫队来处理的.我们先把输入的数字另外排一下序,然后记录一下\(p_i\)表示每一个数字对应在排好序的数列里面是排第几个.询问的时候要把一个询问拆成\( ...

  3. 【bzoj4939】【YNOI2016】掉进兔子洞(莫队)

    题目描述 您正在打galgame,然后突然发现您今天太颓了,于是想写个数据结构题练练手: 一个长为 n 的序列 a. 有 m 个询问,每次询问三个区间,把三个区间中同时出现的数一个一个删掉,问最后三个 ...

  4. P4688-[Ynoi2016]掉进兔子洞【莫队,bitset】

    正题 题目链接:https://www.luogu.com.cn/problem/P4688 题目大意 给出一个长度为nnn的序列aaa. 然后mmm次询问给出三个区间,求这三个区间构成的可重集删去交 ...

  5. 《经济学人》也玩新奇,跟着爱丽丝掉进了兔子洞 | 经济学人全球早报精选

    文 / 王不留(微信公众号:考研英语笔记) 2021年10月26号的清晨,来杯"经济学人浓香咖啡",提神解困. Curiouser and curiouser: The Econo ...

  6. [ NOIP提高组 2016]愤怒的小鸟(暴搜 + 状压DP)// [SNOI2017]一个简单的询问(莫队)

    一次性写两道题 T1:一个简单的询问 题目 题解 代码实现 T2:愤怒的小鸟 题目 暴搜题解 暴搜代码实现 状压DP题解 状压DP代码实现 T1:一个简单的询问 题目 给你一个长度为 N 的序列 ai ...

  7. 《我是一只IT小小鸟》连载九——掉进读书的兔子洞(5)

    /*误打误撞,选择了出国深造*/ 掉进读书的兔子洞 徐宥 误打误撞,选择了出国深造 在找工作的同时,我出国的事情也没闲.我觉得直接靠寄材料申请计算机希望渺茫(我先前直接申请了几家数学和计算机,都是拒信 ...

  8. 2023牛客寒假算法基础集训营4_20230130「向上取整」「夹逼dp」「lowbit科学+树状数组性质」「搜索」「倍增跳表」「莫队」

    6/13 教育场是有被教育到.(预计会鸽几题. 已过非太水的题们 //B //https://ac.nowcoder.com/acm/contest/46812/B//小构造小数学#include & ...

  9. 学习笔记:杨辉三角形上莫队(组合数莫队)(LULU胡策)

    与唐林康的决战在即,面筋哥需要一件压场子的终极武器. 面筋哥手上有 M 个面筋,能量值分别为 1-M 的整数.现在面筋哥想要利用这些面筋制 作他的终极武器:Ex 面筋棒.Ex 面筋棒是一种能够发射强大 ...

  10. 莫队 ---- CF 135D. Jeff and Removing Periods (等差数列预处理 + 莫队)

    题目 题目大意: 给你一个等差序列,每次查询一段区间[l,r][l,r][l,r]的答案. 显然这是典型的不带修改的区间询问类问题,我们可以考虑用莫队算法去解决. 解题思路: 接下来看怎么递推[l,r ...

最新文章

  1. 《评人工智能如何走向新阶段》后记
  2. 运动控制器对比:Windows MR、Rift、Vive、PSVR(译文修正版)
  3. STM8L探索套件学习笔记(转)
  4. C++类与static关键字
  5. java线程实现方式
  6. 延迟关机_苹果电脑到底需不需要关机?关机和休眠你选择哪个
  7. GitHub标星7700:Python从新手到大师,只要100天
  8. 韩顺平java基础学习笔记
  9. 外文文献翻译一条龙 -对于毕设翻译贼有用
  10. 安徽大学计算机科学与技术考研科目,2020安徽大学计算机专业课调整
  11. SCAR:Scalable Consensus Algorithm一种可伸缩共识算法
  12. git push 时出现错误error: failed to push some refs to ‘https://gitee.com/**.git‘
  13. html5 输入用户名和密码登陆网址,360路由器登录网址用户名和密码指南
  14. miui patchrom项目 生成原厂包/java内存溢出解决方法
  15. 华为hcia-datacom 学习日记
  16. OpenShift 4 - 在单机版 OpenShift Local 中运行 OpenShift Virtualization(视频)
  17. 图解数据中心冷热电三联供原理
  18. 昆明理工大学计算机学院研究生录取分数线,2021昆明理工大学研究生分数线一览表(含2019-2020历年复试)...
  19. python3 selenium 模拟登陆 获取cookies 保存到redis(安居客)
  20. 百思不得姐--小程序

热门文章

  1. 【JY】STKO助力OpenSEES系列:结构模态分析以及动力特性(MDOF与等效SDOF验证)
  2. activity劫持学习与复现
  3. 通用计算机的通用性如何体现,计算机的通用性表现在哪方面
  4. android 隐藏电池,Android8.1隐藏状态栏电池图标
  5. 机器学习(1)-项目 0: 预测泰坦尼克号乘客生还率
  6. iReport简单使用
  7. 《精益数据分析》:网易创始人丁磊力荐
  8. 百度推出新版团购导航 对团购导航造成冲击
  9. BZOJ 3555: [Ctsc2014]企鹅QQ
  10. SpringCloud整合Feign和Nacos报错:No Feign Client for loadBalancing defined. Did you forget to include?