### 洛谷P4396  题目链接 ###

题目大意:

有 n 个整数组成的数组,m 次询问,每次询问中有四个参数 l ,r,a,b 。问你在[l,r] 的区间内的所有数中,值属于[a,b] 的数的个数以及种类数。

分析:

1、由于可以离线操作,故采用莫队。

2、由于在莫队的基础上还涉及区间[a,b]的值的个数,故可以用前缀和的思想,求得出sum(b) - sum(a - 1)即可。由于与莫队使用是动态的,故需要用树状数组维护,因为可以 logn 动态插入。

3、对于求区间种类数,需要用第二个树状数组维护。且需要用 cnt[] 数组来标记当前数是否是第一次出现或最后一次出现的数。如果是第一次出现且需 add,则更新当前点以及后置点 + +(树状数组插入);若为最后一次出现且需 del,则更新当前点以及后置点 - - 即可。

4、由于数组中数的范围未给定,在树状数组中可能爆空间,故需要离散化。

算法正确性:

树状数组的原理在于,若当前点值为 x ,则对于所有>= x 的数,都要加上这个数的贡献,即 + + 。比如有 >= x 的数 y ,在求前缀和(即在求 <= y 的数的个数)时,所有出现过的且 <= y 的值的点 x ,都在之前的插入对答案做有贡献。可想而知,树状数组的这种优点导致可以存储前缀和。

然后再注意一下离散化的细节即可,最好在去重的末端加入一个极大值,这样lower_bound 就不会越界,且在求 pos1 以及 pos2 时能很好地判断取值。

然后莫队排序时,需要用到奇偶排序,不然会 T 一个点。

代码如下:

#include<iostream>
#include<algorithm>
#include<string.h>
#include<cmath>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 100008
int n,m,block,len;
int be[maxn];
int g[maxn],f[maxn],d[maxn];
int c[maxn],z[maxn],cnt[maxn];
struct S{
int ans1,ans2;
}s[maxn];
struct Mo{
int id;
int l,r;
int a,b;
}A[maxn];
bool cmp(Mo q,Mo w){
return (be[q.l]^be[w.l])?q.l<w.l:(be[q.l]&)?q.r<w.r:q.r>w.r; //奇偶排序
}
inline int lowbit(int x){return x&(-x);}
void Zupdate(int i,int q){
while(i<=len){
z[i]+=q;
i+=lowbit(i);
}
return;
}
int Zquery(int i){
int ans=;
while(i){
ans+=z[i];
i-=lowbit(i);
}
return ans;
}
void update(int i,int q){
while(i<=len){
c[i]+=q;
i+=lowbit(i);
}
return;
}
inline int query(int i){
int ans=;
while(i){
ans+=c[i];
i-=lowbit(i);
}
return ans;
}
void add(int x){
int pos=d[x];
update(pos,);
if(!cnt[pos]) Zupdate(pos,);
cnt[pos]++;
return;
}
void del(int x){
int pos=d[x];
update(pos,-);
cnt[pos]--;
if(!cnt[pos]) Zupdate(pos,-);
return;
}
int main()
{
scanf("%d%d",&n,&m);
block=sqrt(n);
for(int i=;i<=n;i++) {
scanf("%d",&g[i]);
be[i]=(i-)/block+;//分块
f[i]=g[i];
}
for(int i=;i<=m;i++){
scanf("%d%d%d%d",&A[i].l,&A[i].r,&A[i].a,&A[i].b);
A[i].id=i;
}
sort(A+,A+m+,cmp);
sort(f+,f+n+);
len=unique(f+,f+n+)-f-;
f[len+]=inf;
for(int i=;i<=n;i++) d[i]=lower_bound(f+,f+len+,g[i])-f;// 原数组g[i]中的离散值 d[i]
int l=,r=;
for(int i=;i<=m;i++){
while(l<A[i].l) del(l++);
while(l>A[i].l) add(--l);
while(r<A[i].r) add(++r);
while(r>A[i].r) del(r--);
int pos1=lower_bound(f+,f+len+,A[i].a)-f;
int pos2=lower_bound(f+,f+len+,A[i].b)-f;
if(f[pos2]>A[i].b) pos2--;
s[A[i].id].ans1=query(pos2)-query(pos1-);
s[A[i].id].ans2=Zquery(pos2)-Zquery(pos1-);
}
for(int i=;i<=m;i++) printf("%d %d\n",s[i].ans1,s[i].ans2 );
}

洛谷 P4396 (离散化+莫队+树状数组)的更多相关文章

  1. 【BZOJ3460】Jc的宿舍(树上莫队+树状数组)

    点此看题面 大致题意: 一棵树,每个节点有一个人,他打水需要\(T_i\)的时间,每次询问两点之间所有人去打水的最小等待时间. 伪·强制在线 这题看似强制在线,但实际上,\(pre\ mod\ 2\) ...

  2. bzoj3236 作业 莫队+树状数组

    莫队+树状数组 #include<cstdio> #include<cstring> #include<iostream> #include<algorith ...

  3. BZOJ_3289_Mato的文件管理_莫队+树状数组

    BZOJ_3289_Mato的文件管理_莫队+树状数组 Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号 .为了防止他人 ...

  4. BZOJ3236[Ahoi2013]作业——莫队+树状数组/莫队+分块

    题目描述 输入 输出 样例输入 3 4 1 2 2 1 2 1 3 1 2 1 1 1 3 1 3 2 3 2 3 样例输出 2 2 1 1 3 2 2 1 提示 N=100000,M=1000000 ...

  5. COGS.1822.[AHOI2013]作业(莫队 树状数组/分块)

    题目链接: COGS.BZOJ3236 Upd: 树状数组实现的是单点加 区间求和,采用值域分块可以\(O(1)\)修改\(O(sqrt(n))\)查询.同BZOJ3809. 莫队为\(O(n^{1. ...

  6. bzoj 3289: Mato的文件管理 莫队+树状数组

    3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Mato同学 ...

  7. 51nod 1290 Counting Diff Pairs | 莫队 树状数组

    51nod 1290 Counting Diff Pairs | 莫队 树状数组 题面 一个长度为N的正整数数组A,给出一个数K以及Q个查询,每个查询包含2个数l和r,对于每个查询输出从A[i]到A[ ...

  8. HihoCoder 1488 : 排队接水(莫队+树状数组)

    描述 有n个小朋友需要接水,其中第i个小朋友接水需要ai分钟. 由于水龙头有限,小Hi需要知道如果为第l个到第r个小朋友分配一个水龙头,如何安排他们的接水顺序才能使得他们等待加接水的时间总和最小. 小 ...

  9. BZOJ 3236 莫队+树状数组

    思路: 莫队+树状数组 (据说此题卡常数) yzy写了一天(偷笑) 复杂度有点儿爆炸 O(msqrt(n)logn) //By SiriusRen #include <cmath> #in ...

随机推荐

  1. Nginx学习一路向西

    Nginx 学习一路向北 Java大猿帅成长手册,GitHub JavaEgg ,N线互联网开发必备技能兵器谱 1. Nginx简介 1.1 Nginx 概述 NGINX是一个免费.开源.高性能.轻量 ...

  2. java基础- Java编程规范与注释

    一 前言 java编程规约是指在java代码编写过程中通俗的约定:通常我们是要遵守这些规范:这好比我们在生活中要遵守的道德准则,如果你做的事情超出了道德的底线,那就有可能会受到社会抨击:在java编程 ...

  3. 《Java基础知识》Java 泛型详解

    JDK 1.5 之后,Java 通过泛型解决了容器类型安全这一问题,而几乎所有人接触泛型也是通过Java的容器.那么泛型究竟是什么? 泛型的本质是参数化类型:也就是说,泛型就是将所操作的数据类型作为参 ...

  4. 《Dotnet9》系列-开源C# WPF项目1《Accelerider.Windows》强力推荐

    时间如流水,只能流去不流回! 点赞再看,养成习惯,这是您给我创作的动力! 本文 Dotnet9 https://dotnet9.com 已收录,站长乐于分享dotnet相关技术,比如Winform.W ...

  5. 开源日志框架Exceptionless使用教程

    Exceptionless是一款日志记录框架,它开源.免费.提供管理界面.易于安装和使用.ExceptionLess底层采用ElasticSearch作为日志存储,提供了快速.丰富的查询API,方便我 ...

  6. mysql-5.7.21-winx64安装教程

    1 . 下载对用的版本信息 地址是:https://dev.mysql.com/downloads/mysql/ 2 . 解压到目录 D:\tools\mysql\mysql-5.7.21-winx6 ...

  7. Springboot 错误处理机制

    SpringBoot默认的错误处理机制 即我们常见的白色的ErrorPage页面 浏览器发送的请求头: 如果是其他的请求方式,比如客户端,则相应一个json数据: 原理:是通过 ErrorMvcAut ...

  8. 大数据理论篇 - 通俗易懂,揭秘谷歌《The Dataflow Model》的核心思想(一)

    目录 前言 目标 核心的设计原则 通用的数据处理流程 切合实际的解决方案 总结 延伸阅读 最后 作者:justmine 头条号:大数据达摩院 创作不易,未经授权,禁止转载,否则保留追究法律责任的权利. ...

  9. 深入了解angularjs中的$digest与$apply方法,从区别聊到使用优化

     壹 ❀ 引 如果有人问,在angularjs中修改模型数据为何视图会同步更新呢,我想大多数人一定会回答脏检查(Dirty Checking)相关概念.没错,在angularjs中作用域(scope) ...

  10. Css里的box-shadow的值分别代表什么

    以下为例: box-shadow:1px 2px 3px 4px color inset; 1px:表示沿x轴的正方向的长度(如果是负数,则为沿x轴的负方向的长度); 2px:表示沿y轴的正方向的长度 ...