题目传送门:洛谷P4396

题意简述:

给定一个长度为\(n\)的数列。有\(m\)次询问,每次询问区间\([l,r]\)中数值在\([a,b]\)之间的数的个数,和数值在\([a,b]\)之间的不同的数的个数。

题解:

第一问可以用主席树维护,但是第二问呢?

考虑离线处理询问,用莫队算法。

问题转化为加入一个数,删除一个数,统计数值在一个区间中的数的个数。

离散化后可以用树状数组维护,但是复杂度多个log,变成了\(O(n\sqrt{n}\log n)\)。

考虑对数值也分块,先离散化,然后也是根号分块。修改时是$O(1)$的,查询是$O(\sqrt{n})$的。

那么考虑莫队的复杂度,有\(O(n\sqrt{n})\)次修改,但是只有$O(n)$次查询,那么总复杂度仍然是$O(n\sqrt{n})$。

 #include<bits/stdc++.h>
using namespace std;
#define F(i,a,b) for(int i=(a);i<=(b);++i) int n,q,S,T,U;
int a[],b[],blk[];
struct D{int l,r,a,b,id;}Q[];
bool cmp(D i,D j){return blk[i.l]==blk[j.l]?i.r<j.r:blk[i.l]<blk[j.l];}
int cnt[],bel[],sum[],num[];
pair<int,int> Ans[]; void Ins(int p,int x){
if(!cnt[p]) ++num[bel[p]];
cnt[p]+=x, sum[bel[p]]+=x;
if(!cnt[p]) --num[bel[p]];
} pair<int,int> Qur(int a,int b){
if(a>b) return make_pair(,);
int S=,N=;
if(bel[a]==bel[b]) F(i,a,b) {if(cnt[i]) S+=cnt[i], ++N;}
else{
F(i,bel[a]+,bel[b]-) S+=sum[i], N+=num[i];
F(i,a,bel[a]*U) if(cnt[i]) S+=cnt[i], ++N;
F(i,bel[b]*U-U+,b) if(cnt[i]) S+=cnt[i], ++N;
}
return make_pair(S,N);
} int main(){
scanf("%d%d",&n,&q); S=sqrt(n)+0.5;
F(i,,n) blk[i]=(i-)/S+;
F(i,,n) scanf("%d",a+i), b[i]=a[i];
sort(b+,b+n+); T=unique(b+,b+n+)-b-;
U=sqrt(T)+0.5;
F(i,,T) bel[i]=(i-)/U+;
F(i,,n) a[i]=lower_bound(b+,b+T+,a[i])-b;
F(i,,q) scanf("%d%d%d%d",&Q[i].l,&Q[i].r,&Q[i].a,&Q[i].b), Q[i].id=i;
sort(Q+,Q+q+,cmp);
int L=,R=;
F(i,,q){
while(L>Q[i].l) --L, Ins(a[L],);
while(R<Q[i].r) ++R, Ins(a[R],);
while(L<Q[i].l) Ins(a[L],-), ++L;
while(R>Q[i].r) Ins(a[R],-), --R;
Ans[Q[i].id]=Qur(lower_bound(b+,b+T+,Q[i].a)-b,upper_bound(b+,b+T+,Q[i].b)-b-);
}
F(i,,q) printf("%d %d\n",Ans[i].first,Ans[i].second);
return ;
}

bzoj 3236: 洛谷 P4396: [AHOI2013]作业 (莫队, 分块)的更多相关文章

  1. [AHOI2013]作业 (莫队+分块)

    [AHOI2013]作业 (莫队+分块) 题面 给定了一个长度为n的数列和若干个询问,每个询问是关于数列的区间[l,r],首先你要统计该区间内大于等于a,小于等于b的数的个数,其次是所有大于等于a,小 ...

  2. Bzoj 3236: [Ahoi2013]作业 莫队,分块

    3236: [Ahoi2013]作业 Time Limit: 100 Sec  Memory Limit: 512 MBSubmit: 1113  Solved: 428[Submit][Status ...

  3. 洛谷 P4396 (离散化+莫队+树状数组)

    ### 洛谷P4396  题目链接 ### 题目大意: 有 n 个整数组成的数组,m 次询问,每次询问中有四个参数 l ,r,a,b .问你在[l,r] 的区间内的所有数中,值属于[a,b] 的数的个 ...

  4. 洛谷 P4396 [AHOI2013]作业

    题目描述 题目传送门 分析 因为询问是关于区间的,并且没有强制在线,所以能用莫队解决 但是还要支持查询区间内大于等于 \(a\),小于等于 \(b\) 的数的个数和数值的个数 所以还要套一个数据结构 ...

  5. bzoj3809 Gty的二逼妹子序列 & bzoj3236 [Ahoi2013]作业 莫队+分块

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3809 https://lydsy.com/JudgeOnline/problem.php?id ...

  6. BZOJ3236:[AHOI2013]作业(莫队,分块)

    Description Input Output Sample Input 3 4 1 2 2 1 2 1 3 1 2 1 1 1 3 1 3 2 3 2 3 Sample Output 2 2 1 ...

  7. 洛谷P4396 [AHOI2013]作业(树套树)

    题意 题目链接 Sol 为什么一堆分块呀..三维数点不应该是套路离线/可持久化+树套树么.. 亲测树状数组套权值线段树可过 复杂度\(O(nlog^2n)\),空间\(O(nlogn)\)(离线) # ...

  8. 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 ...

  9. BZOJ 3236: [Ahoi2013]作业( 莫队 + BIT )

    莫队..用两个树状数组计算.时间复杂度应该是O(N1.5logN). 估计我是写残了...跑得很慢... ----------------------------------------------- ...

随机推荐

  1. HDU4641_K-string

    若它的一个子串出现的次数不少于K次,那么这个子串就是一个K-string. 现给出原串,每次可以向该串后面添加一个字符或者询问当前有多少个不同的K-string. 在线添加查询,解法直指SAM. 其实 ...

  2. bzoj1036 [ZJOI2008]树的统计Count(树链剖分)

    Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. Q ...

  3. 一些常用的基础Linux操作指令

    复习的时候顺便分享我学的知识,虽不是什么牛的技术分享,只是一些基础,基础打好了技术慢慢就提高了!一起加油一起共勉! 具体的vi和vim命令集太多了,以后的随笔我也会分享出来,没必要全记住,记住常用的就 ...

  4. P1896 [SCOI2005]互不侵犯

    题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 注:数据有加强(2018/4/25) ...

  5. PHP Warning: strftime(): It is not safe to rely on the system's timezone set

    当运行一些程序时,在httpd日志中会有如下警告日志: PHP Warning:  strftime(): It is not safe to rely on the system's timezon ...

  6. [洛谷P4723]【模板】线性递推

    题目大意:求一个满足$k$阶齐次线性递推数列$a_i$的第$n$项. 即:$a_n=\sum\limits_{i=1}^{k}f_i \times a_{n-i}$ 题解:线性齐次递推,先见洛谷题解, ...

  7. kafka-connect-hive sink实现要点小结

    kafka-connect-hive sink插件实现了以ORC和Parquet两种方式向Hive表中写入数据.Connector定期从Kafka轮询数据并将其写入HDFS,来自每个Kafka主题的数 ...

  8. BZOJ 2724 蒲公英 | 分块模板题

    题意 给出一个序列,在线询问区间众数.如果众数有多个,输出最小的那个. 题解 这是一道分块模板题. 一个询问的区间的众数,可能是中间"整块"区间的众数,也可能是左右两侧零散的数中的 ...

  9. 安装GourdScanV2的踩坑过程

    环境:ubuntu 16.04.1 1.安装dcoker sudo apt-get install docker.io 坑:sudo apt-get install docker 2.下载关于dock ...

  10. 正确理解 LEAL (Load Effective Address) 指令

    LEAL: leal S, D    ->    D ← &S 在 CSAPP (Computer Systems: A Programmer’s Perspective) 中,对 LE ...