Description

Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题。
对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数。
为了方便,我们规定妹子们的美丽度全都在[1,n]中。
给定一个长度为n(1<=n<=100000)的正整数序列s(1<=si<=n),对于m(1<=m<=1000000)次询问“l,r,a,b”,每次输出sl...sr中,权值∈[a,b]的权值的种类数。

Input

第一行包括两个整数n,m(1<=n<=100000,1<=m<=1000000),表示数列s中的元素数和询问数。
第二行包括n个整数s1...sn(1<=si<=n)。
接下来m行,每行包括4个整数l,r,a,b(1<=l<=r<=n,1<=a<=b<=n),意义见题目描述。
保证涉及的所有数在C++的int内。
保证输入合法。

Output

对每个询问,单独输出一行,表示sl...sr中权值∈[a,b]的权值的种类数。

Sample Input

10 10
4 4 5 1 4 1 5 1 2 1
5 9 1 2
3 4 7 9
4 4 2 5
2 3 4 7
5 10 4 4
3 9 1 1
1 4 5 9
8 9 3 3
2 2 1 6
8 9 1 4

Sample Output

2
0
0
2
1
1
1
0
1
2
 
 
题意概述:给出一个序列,每次询问问序列区间[L,R]中的元素里权值在[a,b]中的不同元素种类数。
总的一句话:所有可以用O(1)时间(总之就是代价很小)把区间[l,r]的询问转化到区间[l+1,r],[l,r-1]的询问的可离线问题都可以用莫队干掉!
观察这个问题,可以发现如果你维护一个维护元素的数据结构,那么显然可以在你移动区间左右指针的时候做到快速修改答案,这正符合了莫队算法的用途。
使用分块来做这个维护元素的数据结构,因为它支持O(1)修改啊!每一次查询的时候时间复杂度和移动指针的时间代价是几乎相同的。
 
时间复杂度O((2N+M)*sqrt(N))
 
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
const int MAXN=;
const int MAXQ=;
const int size=; int N,M,S[MAXN],ans[MAXQ];
struct que{
int id,l,r,a,b;
friend bool operator < (que a,que b){
return a.l/size<b.l/size||a.l/size==b.l/size&&a.r<b.r;
}
}q[MAXQ];
struct BLOCK{
static const int maxn=;
static const int SIZE=;
static const int maxm=;
int c[maxn],kind[maxm],lef[maxm],rig[maxm],cnt,belong[maxn];
BLOCK(){ cnt=; }
void build(int n){
int p=;
while(p+SIZE<n+){
lef[cnt]=p,rig[cnt]=p+SIZE,p+=SIZE,cnt++;
for(int i=lef[cnt-];i<rig[cnt-];i++) belong[i]=cnt-;
}
lef[cnt]=p,rig[cnt]=n+;
for(int i=lef[cnt];i<rig[cnt];i++) belong[i]=cnt;
}
void update(int p,int v){
if(c[p]&&c[p]+v==) kind[belong[p]]--;
if(!c[p]&&c[p]+v==) kind[belong[p]]++;
c[p]+=v;
}
int query(int L,int R){
int re=,p=L;
if(belong[L]==belong[R]){
for(int i=L;i<=R;i++) if(c[i]) re++;
return re;
}
for(int i=L;i<rig[belong[L]];i++) if(c[i]) re++;
for(int i=lef[belong[R]];i<=R;i++) if(c[i]) re++;
for(int i=belong[L]+;i<belong[R];i++) re+=kind[i];
return re;
}
}block; void _scanf(int &x)
{
x=;
char c=getchar();
while(c<''||c>'') c=getchar();
while(c>=''&&c<='') x=x*+c-'',c=getchar();
}
int out_cnt,out[];
void _printf(int x)
{
out[++out_cnt]=x%,x/=;
while(x) out[++out_cnt]=x%,x/=;
while(out_cnt) putchar(''+out[out_cnt--]);
putchar('\n');
}
void data_in()
{
_scanf(N);_scanf(M);
for(int i=;i<=N;i++) _scanf(S[i]);
for(int i=;i<=M;i++){
_scanf(q[i].l);_scanf(q[i].r);
_scanf(q[i].a);_scanf(q[i].b);
q[i].id=i;
}
}
void movep(int &i,int j,int t)
{
while(i<j){
if(!t) block.update(S[i++],-);
else block.update(S[++i],);
}
while(i>j){
if(!t) block.update(S[--i],);
else block.update(S[i--],-);
}
}
void work()
{
sort(q+,q+M+);
block.build(N);
int l=,r=;
block.update(S[],);
for(int i=;i<=M;i++){
movep(r,q[i].r,);
movep(l,q[i].l,);
ans[q[i].id]=block.query(q[i].a,q[i].b);
}
for(int i=;i<=M;i++) _printf(ans[i]);
}
int main()
{
data_in();
work();
return ;
}

BZOJ 3809 Gty的二逼妹子序列 莫队算法+分块的更多相关文章

  1. Bzoj 3809: Gty的二逼妹子序列 莫队,分块

    3809: Gty的二逼妹子序列 Time Limit: 35 Sec  Memory Limit: 28 MBSubmit: 868  Solved: 234[Submit][Status][Dis ...

  2. bzoj 3809 Gty的二逼妹子序列 —— 莫队+分块

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3809 据说一开始应该想到莫队+树状数组,然而我想的却是莫队+权值线段树... 如果用权值线段 ...

  3. bzoj 3809 Gty的二逼妹子序列——莫队+分块

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3809 容易想到树状数组维护值域.但修改和查询都是 log 太慢. 考虑有 nsqrt(n) ...

  4. BZOJ 3809: Gty的二逼妹子序列

    3809: Gty的二逼妹子序列 Time Limit: 80 Sec  Memory Limit: 28 MBSubmit: 1387  Solved: 400[Submit][Status][Di ...

  5. [AHOI2013]作业 & Gty的二逼妹子序列 莫队

    ---题面--- 题解: 题目要求统计一个区间内数值在[a, b]内的数的个数和种数,而这个是可以用树状数组统计出来的,所以可以考虑莫队. 考虑区间[l, r]转移到[l, r + 1],那么对于维护 ...

  6. [ AHOI 2013 ] 作业 & [ BZOJ 3809 ] Gty的二逼妹子序列

    \(\\\) Description 给出一个长为 \(n\) 的数列 \(A\) 和 \(k\),多次询问: 对于一个区间 \([L_i,R_i]\),问区间内有多少个数在 \([a_i,b_i]\ ...

  7. BZOJ 3809 Gty的二逼妹子序列(莫队+分块)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3809 [题目大意] 给定一个长度为n(1<=n<=100000)的正整数序 ...

  8. [BZOJ3809]Gty的二逼妹子序列[莫队+分块]

    题意 给出长度为 \(n\) 的序列,\(m\) 次询问,每次给出 \(l,r,a,b\) ,表示询问区间 \([l,r]\) 中,权值在 \([a,b]\) 范围的数的种类数. \(n\leq 10 ...

  9. bzoj 3809 Gty的二逼妹子序列(莫队算法,块状链表)

    [题意] 回答若干个询问,(l,r,a,b):区间[l,r]内权值在[a,b]的数有多少[种]. [思路] 考虑使用块状链表实现莫队算法中的插入与删除. 因为权值处于1..n之间,所以我们可以建一个基 ...

随机推荐

  1. detection工作

    今天看到YOLO2的工作还是很不错的,效果好,关键是速度也快,已经完胜SSD了感觉. 虽然faster rcnn各方面效果都不错,但是从简单粗暴的角度考虑,SSD和YOLO真的深得我心啊. 检测模型, ...

  2. android imageview使用的时候 引用资源src和background的区别

    android imageview使用的时候 引用资源时src和background的区别 src更强调内容并且不行拉伸图片进行适配,而background更注重引用图片,会对图片进行拉伸

  3. Redis集群的安装和使用

  4. 为什么IP检验和发现错误直接丢弃而不是要求源站重发

    纠错控制由上层(传输层)执行IP首部中的源站地址也可能出错,请错误的源地址重传数据报是 没有意义的

  5. javascript 中数组的创建 添加 与将数组转换成字符串 页面三种提交请求的方式

    创建js数组 var array=new Array(); Java中创建数组 private String[] array=new String[3]; 两个完全不同的,js中是可变长度的 添加内容 ...

  6. 利用C++中采用面向对象的思想顺序表

    最近在复习数据结构,我用面向对象的思想实现了顺序表,采用C++语言. 首先建立在Visual Studio 2017中建立一个工程,然后新建一个类SqList.然后会生成SqList.h和SqList ...

  7. springboot properties文件中的数据通过@Value()形式注入

    首先在resources目录下新建一个properties文件,如下图 在photoPath.properties中写入内容,key=value的形式,如下图 在你需要引用properties的类头部 ...

  8. Linux中查看已安装内存与交换空间使用情况

    目录   1. free查看内存使用量   2. 查看 /proc/meminfo 文件获取物理内存信息   3. top命令获取内存用量 1. free查看内存用量命令 该命令是专门用于查看内存用量 ...

  9. Leecode刷题之旅-C语言/python-1.两数之和

    开学后忙的焦头烂额(懒得很),正式开始刷leecode的题目了. 想了想c语言是最最基础的语言,虽然有很多其他语言很简单,有更多的函数可以用,但c语言能煅炼下自己的思考能力.python则是最流行的语 ...

  10. SPLIT(文字列の分割)

    概要 SPLIT命令は特定の文字で値を分割する命令だ.タブ区切りや.カンマ区切り等のファイルからデータを取得し値を各項目に振り分けたい時に使用する事が多いだろう.また.XMLファイル等を使用してインタ ...