LOJ #6285. 数列分块入门 9-分块(查询区间的最小众数)
题目描述
给出一个长为 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-分块(查询区间的最小众数)的更多相关文章
- loj#6285 数列分块入门 9 ( 回 滚 )
题目 : 链接 :https://loj.ac/problem/6285 题意:给出一个长为 n的数列,以及 n个操作,操作涉及询问区间的最小众数. 思路:虽然这不是一道 回滚莫队题,就是 暴力分块 ...
- LOJ#6285. 数列分块入门 9
有点难..... 要求区间众数,所以我可以先把区间分块,然后我预处理出从第 i 块到第 j 块的众数,用dp[i][j]记录下来. 因为需要知道众数的num值, 所以我可以用一个vector来保存每个 ...
- LOJ.6284.数列分块入门8(分块)
题目链接 \(Description\) 给出一个长为n的数列,以及n个操作,操作涉及区间询问等于一个数c的元素,并将这个区间的所有元素改为c. \(Solution\) 模拟一些数据可以发现,询问后 ...
- LOJ.6281.数列分块入门5(分块 区间开方)
题目链接 int内的数(也不非得是int)最多开方4.5次就变成1了,所以还不是1就暴力,是1就直接跳过. #include <cmath> #include <cstdio> ...
- #6278. 数列分块入门 2(询问区间内小于某个值 xx 的元素个数)
题目链接:https://loj.ac/problem/6278 题目大意:中文题目 具体思路:数列分块模板题,对于更新的时候,我们通过一个辅助数组来进行,对于原始的数组,我们只是用来加减,然后这个辅 ...
- LibreOJ 6277 数列分块入门 1(分块)
题解:感谢hzwer学长和loj让本蒟蒻能够找到如此合适的入门题做. 这是一道非常标准的分块模板题,本来用打标记的线段树不知道要写多少行,但是分块只有这么几行,极其高妙. 代码如下: #include ...
- LibreOJ 6280 数列分块入门 4(分块区间加区间求和)
题解:分块的区间求和比起线段树来说实在是太好写了(当然,复杂度也高)但这也是没办法的事情嘛.总之50000的数据跑了75ms左右还是挺优越的. 比起单点询问来说,区间询问和也没有复杂多少,多开一个su ...
- LibreOJ 6278 数列分块入门 2(分块)
题解:非常高妙的分块,每个块对应一个桶,桶内元素全部sort过,加值时,对于零散块O(sqrt(n))暴力修改,然后暴力重构桶.对于大块直接整块加.查询时对于非完整块O(sqrt(n))暴力遍历.对 ...
- [Libre 6281] 数列分块入门 5 (分块)
水一道入门分块qwq 题面:传送门 开方基本暴力.. 如果某一个区间全部都开成1或0就打上标记全部跳过就行了 因为一个数开上个四五六次就是1了所以复杂度能过233~ code: //By Menteu ...
随机推荐
- Nginx与Apache工作方式
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://going.blog.51cto.com/7876557/1304204 Ngin ...
- 图论:最短路-SPFA
该算法由Bellman-Ford算法演变过来,首先介绍一下Bellman-Ford算法 最短路最多经过n-1个点,可以用n-1轮松弛操作来得到 ;i<n;i++) d[i]=INF; d[]=; ...
- 2015/9/1 Python基础(6):列表
列表和字符串类型很相似,是同样的序列式数据类型.但是字符串只能由字符组成,列表可以保留任意数目的Python对象的灵活的容器.Python的列表比C的数组要灵活,数组里面只能是一种类型,列表可以有多种 ...
- svn: Checksum mismatch while updating 错误
最近使用svn客户端更新代码的时候出现 Checksum mismatch while updating 的错误 解决办法 在出错文件的目录下,用update to reversion , 先选onl ...
- PHP系统编程--01.多进程与多线程
PHP中提供了一个扩展pcntl,可以利用操作系统的fork调用来实现多进程.fork调用后执行的代码将是并行的. PHP官方没有提供多线程的扩展,pecl中有一个pthreads扩展提供了多线程的特 ...
- hihocoder1445 后缀自动机二·重复旋律5
传送门:http://hihocoder.com/problemset/problem/1445 [题解] 大概看了一天的后缀自动机,总算懂了一些 这篇文章写的非常好,诚意安利:Suffix Auto ...
- 【转载】Quick-Cocos2d-x文件结构分析
在上一章我们讲过了Quick-Cocos2d-x中的环境搭建,这章我们分析下quick中的文件结构吧!打开quick的文件夹,可以看到如下的这些目录和文件: bin:存放各种与引擎相关的脚本 comp ...
- CSS 竖线 点 时间节点
效果如图 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- 2.0 docker安装
问题列表: Error: Cannot retrieve metalink for repository: epel. Please verify its path and try again 解:处 ...
- JSX语法规范
1.只有一个开始节点和一个尾节点 正确的写法 ReactDOM.render( <div>hello,你好</div>, document.body ) 错误的写法,开始节点和 ...