内存限制:256 MiB时间限制:1500 ms标准输入输出
题目类型:传统评测方式:文本比较
上传者: hzwer

题目描述

给出一个长为 nn 的数列,以及 nn 个操作,操作涉及询问区间的最小众数。

输入格式

第一行输入一个数字 nn。

第二行输入 nn 个数字,第 ii 个数字为 a_iai​,以空格隔开。

接下来输入 nn 行询问,每行输入两个数字 ll、rr,以空格隔开。

表示查询位于 [l,r][l,r] 的数字的众数。

输出格式

对于每次询问,输出一行一个数字表示答案。

样例

样例输入

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

样例输出

1
2
2
2

数据范围与提示

对于 100\%100% 的数据,1 \leq n \leq 100000, -2^{31} \leq \mathrm{others}1≤n≤100000,−231≤others、\mathrm{ans} \leq 2^{31}-1ans≤231−1。

这道题,我交了82发,微笑:)

分块根号n是过不去的,是的,开80长度可以过,然后要打标记,查询的时候前一部分找过的,就打标记后一部分就不用再找了。

然后就是标记要用bool型,开int过不了,重新编号要用map,int过不了,还有就是主函数预处理的时候,块数是n/m+1,不再是m+1。

以上都是踩过的坑,灰常开心,写到自闭,最后看了别人的,发现长度开大了,改了就过了。

代码:

 //#6285. 数列分块入门 9-查询区间的最小众数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+;
const int maxm=2e3+; int n,m,id=;
int a[maxn],pos[maxn],val[maxn];
int c[maxn],f[maxm][maxm];
vector<int> vec[maxn];
map<int,int> b;
bool vis[maxn]; #define reads(n) FastIO::read(n)
namespace FastIO
{
const int SIZE = << ;
char buf[SIZE], obuf[SIZE], str[];
int bi = SIZE, bn = SIZE, opt;
int read(char *s)
{
while (bn)
{
for (; bi < bn && buf[bi] <= ' '; bi++);
if (bi < bn)
break;
bn = fread(buf, , SIZE, stdin);
bi = ;
}
int sn = ;
while (bn)
{
for (; bi < bn && buf[bi] > ' '; bi++)
s[sn++] = buf[bi];
if (bi < bn)
break;
bn = fread(buf, , SIZE, stdin);
bi = ;
}
s[sn] = ;
return sn;
}
bool read(int& x)
{
int n = read(str), bf;
if (!n)
return ;
int i = ;
if (str[i] == '-')
bf = -, i++;
else
bf = ;
for (x = ; i < n; i++)
x = x * + str[i] - '';
if (bf < )
x = -x;
return ;
}
}; void init(int x)
{
// for(int i=0;i<=1e5+10;i++)
// c[i]=0;
int nummax=,maxx=;
memset(c,,sizeof(c));
for(int i=(x-)*m+;i<=n;i++){
c[a[i]]++;
if(c[a[i]]>nummax||(c[a[i]]==nummax&&val[a[i]]<val[maxx])){
nummax=c[a[i]];
maxx=a[i];
}
f[x][pos[i]]=maxx;
}
} int length(int l,int r,int val)
{
return upper_bound(vec[val].begin(),vec[val].end(),r)-lower_bound(vec[val].begin(),vec[val].end(),l);
} int query(int l,int r)
{
int maxx=f[pos[l]+][pos[r]-],nummax=;
memset(vis,,sizeof(vis));
nummax=length(l,r,maxx);
vis[maxx]=;
for(int i=l;i<=min(pos[l]*m,r);i++){
if(vis[a[i]]==){
vis[a[i]]=;
int ret=length(l,r,a[i]);
if(ret>nummax||(ret==nummax&&val[a[i]]<val[maxx])){
nummax=ret;
maxx=a[i];
}
}
}
if(pos[l]!=pos[r]){
for(int i=(pos[r]-)*m+;i<=r;i++){
if(vis[a[i]]==){
vis[a[i]]=;
int ret=length(l,r,a[i]);
if(ret>nummax||(ret==nummax&&val[a[i]]<val[maxx])){
nummax=ret;
maxx=a[i];
}
}
}
}
return val[maxx];
} int main()
{
// reads(n);
scanf("%d",&n);
// m=sqrt(n);
m=;
for(int i=;i<=n;i++){
// reads(a[i]);
scanf("%d",&a[i]);
pos[i]=(i-)/m+;
if(b[a[i]]==){
b[a[i]]=++id;
val[id]=a[i];
}
a[i]=b[a[i]];
vec[a[i]].push_back(i);
}
// for(int i=1;i<=pos[n];i++){
for(int i=;i<=n/m+;i++){//块长为m,那么最多为n/m+1个块
init(i);
}
for(int i=;i<=n;i++){
int l,r;
// reads(l);
// reads(r);
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r));
}
}

完结,再见分块!

LOJ #6285. 数列分块入门 9-分块(查询区间的最小众数)的更多相关文章

  1. loj#6285 数列分块入门 9 ( 回 滚 )

    题目 :  链接 :https://loj.ac/problem/6285 题意:给出一个长为 n的数列,以及 n个操作,操作涉及询问区间的最小众数. 思路:虽然这不是一道 回滚莫队题,就是 暴力分块 ...

  2. LOJ#6285. 数列分块入门 9

    有点难..... 要求区间众数,所以我可以先把区间分块,然后我预处理出从第 i 块到第 j 块的众数,用dp[i][j]记录下来. 因为需要知道众数的num值, 所以我可以用一个vector来保存每个 ...

  3. LOJ.6284.数列分块入门8(分块)

    题目链接 \(Description\) 给出一个长为n的数列,以及n个操作,操作涉及区间询问等于一个数c的元素,并将这个区间的所有元素改为c. \(Solution\) 模拟一些数据可以发现,询问后 ...

  4. LOJ.6281.数列分块入门5(分块 区间开方)

    题目链接 int内的数(也不非得是int)最多开方4.5次就变成1了,所以还不是1就暴力,是1就直接跳过. #include <cmath> #include <cstdio> ...

  5. #6278. 数列分块入门 2(询问区间内小于某个值 xx 的元素个数)

    题目链接:https://loj.ac/problem/6278 题目大意:中文题目 具体思路:数列分块模板题,对于更新的时候,我们通过一个辅助数组来进行,对于原始的数组,我们只是用来加减,然后这个辅 ...

  6. LibreOJ 6277 数列分块入门 1(分块)

    题解:感谢hzwer学长和loj让本蒟蒻能够找到如此合适的入门题做. 这是一道非常标准的分块模板题,本来用打标记的线段树不知道要写多少行,但是分块只有这么几行,极其高妙. 代码如下: #include ...

  7. LibreOJ 6280 数列分块入门 4(分块区间加区间求和)

    题解:分块的区间求和比起线段树来说实在是太好写了(当然,复杂度也高)但这也是没办法的事情嘛.总之50000的数据跑了75ms左右还是挺优越的. 比起单点询问来说,区间询问和也没有复杂多少,多开一个su ...

  8. LibreOJ 6278 数列分块入门 2(分块)

     题解:非常高妙的分块,每个块对应一个桶,桶内元素全部sort过,加值时,对于零散块O(sqrt(n))暴力修改,然后暴力重构桶.对于大块直接整块加.查询时对于非完整块O(sqrt(n))暴力遍历.对 ...

  9. [Libre 6281] 数列分块入门 5 (分块)

    水一道入门分块qwq 题面:传送门 开方基本暴力.. 如果某一个区间全部都开成1或0就打上标记全部跳过就行了 因为一个数开上个四五六次就是1了所以复杂度能过233~ code: //By Menteu ...

随机推荐

  1. Base class does not contain a constructor that takes '0' argument

    刚刚在写一段直播室网站中的一段程序遇,突然遇到一个错误,如下 'TVLLKBLL.BaseClass' does not contain a constructor that takes 0 argu ...

  2. Test Index

    top1 top11 top2 top1 top11 top2

  3. MyBatis框架的使用及源码分析(八) MapperMethod

    从 <MyBatis框架中Mapper映射配置的使用及原理解析(七) MapperProxy,MapperProxyFactory> 文中,我们知道Mapper,通过MapperProxy ...

  4. 【BZOJ1093】【ZJOI2007】最大半联通子图 [DP][Tarjan]

    最大半连通子图 Time Limit: 30 Sec  Memory Limit: 162 MB[Submit][Status][Discuss] Description 一个有向图G=(V,E)称为 ...

  5. Quick-Cocos2dx-Community_3.6.3_Release 编译时libtiff.lib 无法解析

    Quick-Cocos2dx-Community_3.6.3_Release 使用VS2012编译,报错: libtiff.lib lnk2001 无法解析的外部符号 ltod3 类似于上面这种,刚才 ...

  6. 崩坏3mmd中的渲染技术研究

    http://youxiputao.com/articles/11839 主要是参考该篇文章做一个微小的复盘. 漫反射与高光 文章中的漫反射与高光并不是类似于普通的 resultCol = Diffu ...

  7. C# 获取一段日期内的工作日

    /// <summary> /// 根据指定时间段计算工作日天数 /// </summary> /// <param name="firstDay"& ...

  8. hdu 3371(prim算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3371 Connect the Cities Time Limit: 2000/1000 MS (Jav ...

  9. Eureka服务续约(Renew)源码分析

    主要对Eureka的Renew(服务续约),从服务提供者发起续约请求开始分析,通过阅读源码和画时序图的方式,展示Eureka服务续约的整个生命周期.服务续约主要是把服务续约的信息更新到自身的Eurek ...

  10. Caffe 学习笔记1

    Caffe 学习笔记1 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和 ...