题目传送门


题目描述

此时已是凌晨两点,刚刚做了$Codeforces$的小$A$掏出了英语试卷。英语作业其实不算多,一个小时刚好可以做完。然后是一个小时可与做完的数学作业,接下来是分别都是一个小时可以做完的化学,物理,语文……小$A$压力巨大。
    这时小$A$碰到了一道非常恶心的数学题,给定了一个长度为$n$的数列和若干个询问,每个询问是关于数列的区间$[l,r]$(表示数列的第$1$个数到第$r$个数),首先你要统计该区间内大于等于$a$,小于等于$b$的书的个数,其次是所有大于等于$a$,小于等于$b$的,且在该区间中出现过的数值的个数。
    小$A$望着那数万的数据规模几乎绝望,只能向大神您求救,请您帮帮他吧。


输入格式

 第一行两个数$n,m$,接下来$n$个数(这些数都大于等于$1$小于等于$n$),表示给定数列。
 接下来$m$行,每行四个整数$l,r,a,b$:$l,r$表示询问的区间,$a,b$表示询问的数值的范围。


输出格式

 输出$m$行,分别对应每个询问,输出两个数,分别为在l到r这段区间中大小在$[a,b]$中的数的个数,以及大于等于$a$,小于等于$b$的,且在该区间中出现过的数值的个数(具体可以参考样例)。


样例

样例输入

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=100,000$,$m=1,000,000$


题解

为了防止你们数错0,我专门在百万位和十万位之间加了“,”。

但是$n$却只有$100,000$,那么我们可以考虑莫队,至于统计答案,分块就好了。

不过正解好像是用权值线段树或者是树状数组,但是分块常数较小,跑得不比线段书慢。


代码时刻

#include<bits/stdc++.h>
using namespace std;
struct rec
{
int l;
int r;
int a;
int b;
int id;
int p;
}q[1000001];
int n,m;
int t,tt;
int a[1000001];
int lx[1000001],rx[1000001];
int cnt[1000001],pos[1000001],k[1000001],change[1000001];
int ans1[1000001],ans2[1000001];
bool cmp(rec a,rec b){return a.p==b.p?a.r<b.r:a.p<b.p;}//莫队
void get_answer(int l,int r,int id)//分块找答案
{
if(pos[l]==pos[r])
{
for(int i=l;i<=r;i++)
{
ans1[id]+=cnt[i];
if(cnt[i])ans2[id]++;
}
return;
}
if(pos[l])
for(int i=l;i<=rx[pos[l]];i++)
{
ans1[id]+=cnt[i];
if(cnt[i])ans2[id]++;
}
if(pos[r])
for(int i=lx[pos[r]];i<=r;i++)
{
ans1[id]+=cnt[i];
if(cnt[i])ans2[id]++;
}
if(pos[l]&&pos[r])
for(int i=pos[l]+1;i<pos[r];i++){ans1[id]+=k[i];ans2[id]+=change[i];}
if(pos[l]&&!pos[r])
for(int i=pos[l]+1;i<=tt;i++){ans1[id]+=k[i];ans2[id]+=change[i];}
}
int main()
{
scanf("%d%d",&n,&m);
t=sqrt(n);
tt=n/t;
if(n%t)tt++;
for(int i=1;i<=tt;i++)
{
lx[i]=(i-1)*t+1;
rx[i]=i*t;
}
rx[tt]=n;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&q[i].l,&q[i].r,&q[i].a,&q[i].b);
q[i].id=i;
q[i].p=(q[i].l-1)/t+1;
pos[i]=(i-1)/t+1;
}
sort(q+1,q+m+1,cmp);
int l=1,r=0;
for(int i=1;i<=m;i++)
{
while(l<q[i].l)
{
cnt[a[l]]--;
k[pos[a[l]]]--;
if(!cnt[a[l]])change[pos[a[l]]]--;
l++;
}
while(l>q[i].l)
{
l--;
if(!cnt[a[l]])change[pos[a[l]]]++;
cnt[a[l]]++;
k[pos[a[l]]]++;
}
while(r<q[i].r)
{
r++;
if(!cnt[a[r]])change[pos[a[r]]]++;
cnt[a[r]]++;
k[pos[a[r]]]++;
}
while(r>q[i].r)
{
cnt[a[r]]--;
k[pos[a[r]]]--;
if(!cnt[a[r]])change[pos[a[r]]]--;
r--;
}
get_answer(q[i].a,q[i].b,q[i].id);
}
for(int i=1;i<=m;i++)
printf("%d %d\n",ans1[i],ans2[i]);
return 0;
}

rp++

[BZOJ3236]:[Ahoi2013]作业(莫队+分块)的更多相关文章

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

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

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

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

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

  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. Bzoj 3236: [Ahoi2013]作业 莫队,分块

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

  6. bzoj 3236: 洛谷 P4396: [AHOI2013]作业 (莫队, 分块)

    题目传送门:洛谷P4396. 题意简述: 给定一个长度为\(n\)的数列.有\(m\)次询问,每次询问区间\([l,r]\)中数值在\([a,b]\)之间的数的个数,和数值在\([a,b]\)之间的不 ...

  7. 【bzoj3809/bzoj3236】Gty的二逼妹子序列/[Ahoi2013]作业 莫队算法+分块

    原文地址:http://www.cnblogs.com/GXZlegend/p/6805252.html bzoj3809 题目描述 Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了 ...

  8. 【BZOJ3809/3236】Gty的二逼妹子序列 [Ahoi2013]作业 莫队算法+分块

    [BZOJ3809]Gty的二逼妹子序列 Description Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题. 对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b ...

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

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

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

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

随机推荐

  1. Java第五周作业+总结

    实验三 String类的应用 实验目的 掌握类String类的使用: 学会使用JDK帮助文档: 实验内容 1.已知字符串:"this is a test of java".按要求执 ...

  2. 如何去完成一个html网页

    其实我也是菜鸟一个,不过我还是想说说,昨晚看的视频好回忆回忆. 看到这样一个网页我们要怎么入手,这个就要像庖丁解牛一样,我们要对它的各个位置都要了解,分析出页面的结构,要有一个总体的把握,先把这个页面 ...

  3. 如何在centos6和centos7上部署nfs共享服务器和客户端

    nfs共享服务为中小型企业在存储上提供了有效的节省空间,许多大型的网站也在使用nfs,如百度和阿里等,下面结合自己所学的知识,阐述如何在centos6和centos7下配置nfs.注:除了必要的说明外 ...

  4. HNUSTOJ-1698 送外卖(TSP问题 + 状态压缩DP)

    1698: 送外卖 时间限制: 1 Sec  内存限制: 128 MB提交: 123  解决: 28[提交][状态][讨论版] 题目描述 在美团和饿了么大行其道的今天,囊中羞涩的小周和小美,也随大流加 ...

  5. Python设置

    1.中断程序执行 在命令行中中断正在执行的程序,ctrl c或者ctrl break 2.SyntaxError: Non-ASCII character 需要在最开始的地方加上 : #-*-codi ...

  6. 记录一次TabBar使用本地图片

    方法一: 第一步:import  addpng  from '../../assets/img/add.png' 第二步: { title: '找折扣', image: addpng}, 即可. 方法 ...

  7. 6.css3定位--position

    ⑴Static默认值,没有定位. ⑵Absolute绝对定位.后面的元素会补上原来偏移的位置. ⑶Relative相对定位.后面的元素不会补上原来偏移的位置. ⑷Fixed绝对定位.相对于浏览器窗口固 ...

  8. vue项目,webpack中配置src路径别名及使用

    1.项目结构: 2.在build文件夹下的webpack.base.conf.js文件中设置src的路径别名. 3.在js文件或者vue文件的script标签中使用: (1).js文件中导入示例: ( ...

  9. AVCaptureSession拍照,摄像,载图总结

    AVCaptureSession [IOS开发]拍照,摄像,载图总结 1 建立Session  2 添加 input  3 添加output  4 开始捕捉 5 为用户显示当前录制状态 6 捕捉 7 ...

  10. vlan的三种模式access、trunk、hybrid

    untag就是普通的ethernet报文,普通PC机的网卡是可以识别这样的报文进行通讯:tag报文结构的变化是在源mac地址和目的mac地址之后,加上了4bytes的vlan信息,也就是vlan ta ...