题目链接

题目

Description

给定一个非递减数列Ai,你只需要支持一个操作:求一段区间内出现最多的数字的出现次数。

Input

第一行两个整数N,Q

接下来一行有N个整数,表示这个序列。

接下来Q行每行一个操作:A B,询问A到B之间出现最多的数字。

1<=N,Q<=100000。-100000<=Ai<=100000

Output

每组数据若干行,每行对应一个询问的答案。

Sample Input

10 3
-1 -1 1 1 1 1 3 10 10 10
2 3
1 10
5 10

Sample Output

1
4
3

题解

这个题是ST表+RMQ模版题

首先题中所给序列是非递减序列,所有相等的数都会聚在一块,所以我们可以将相等的数字划为一段,\(value[i]和cnt[i]\)分别表示第i段对应的数值和出现的次数,\(num[p],L[p],R[p]\)分别表示位置p所在段的编号和左右端点的位置,每次查询(l, r)的结果分为三部分的最大值,从\(l到l\)所在段的右端点的元素个数(\(R[l]-l+1\)),从r所在段的左端点到r的元素个数(\(r-L[r]+1\)),中间第\(num[l]+1段到num[r]-1\)段cnt的最大值,这样就可以用rmq解决了。

顺便复习一下ST+RMQ

时间复杂度:预处理\(o(nlogn)\),查询\(o(1)\)

\(st[i][j]\)表示从i开始,长度为\(2^j\)的一段元素中的最小(大)值,则可以用递推的方式计算\(st[i][j]\)

\[st[i][j]=min(st[i][j-1],st[i+2^{j-1}][j-1])
\]

循环的时候注意先枚举区间长度,即先枚举j,再枚举起点i,从小区间到大区间。

查询也很简单,查询(L,R)区间内的最小(大)值,直接令x为满足\(2^x \le R-L+1\)的最大整数,则以L开头,R结尾的两个长度为\(2^x\)的区间覆盖了(L,R),由于是取最小值,所以有些元素考虑多遍也没关系,故ST表不能用于区间和

AC代码

#include<bits/stdc++.h>
#define maxn 100005
using namespace std; int a[maxn];
int value[maxn], cnt[maxn], num[maxn], L[maxn], R[maxn];
int st[maxn][20], lg2[maxn];
int n, q;
int k; void ST() {
for (int i = 1; i <= k; i++) {
st[i][0] = cnt[i];
}
for (int j = 1; (1 << j) <= k; j++) {
for (int i = 1; (i + (1 << j) - 1) <= k; i++) {
st[i][j] = max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
}
}
for (int i = 2; i <= k; i++) {
lg2[i] = lg2[i >> 1] + 1;
}
} int rmq(int l, int r) {
if (l>r)
return 0;
else {
int x = lg2[r - l + 1];
return max(st[l][x], st[r - (1 << x) + 1][x]);
}
} int main() {
scanf("%d%d", &n, &q);
k = 0;
value[0] = 0x3f3f3f3f;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
if (a[i] != value[k]) {
R[k] = i;
value[++k] = a[i];
L[k] = i - 1;
cnt[k] = 1;
num[i] = k;
}
else {
cnt[k]++;
num[i] = num[i - 1];
}
}
R[k] = n + 1;
ST();
while (q--) {
int l, r;
scanf("%d%d", &l, &r);
if (num[l] == num[r]) {
printf("%d\n", r - l + 1);
}
else {
int tmp = max(R[num[l]] - l, r - L[num[r]]);
int ans = max(tmp, rmq(num[l] + 1, num[r] - 1));
printf("%d\n", ans);
}
}
return 0;
} /**********************************************************************
Problem: 2221
User: Artoriax
Language: C++
Result: AC
Time:128 ms
Memory:12572 kb
**********************************************************************/

CSU-2221 假装是区间众数(ST表模版题)的更多相关文章

  1. $ST表刷题记录$

    \(st表的题目不太多\) 我做过的就这些吧. https://www.luogu.org/problemnew/show/P3865 https://www.luogu.org/problemnew ...

  2. hdu5443 ST表裸题:求区间最大

    #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #d ...

  3. 51nod(1174 区间中最大的数)(ST表模板题)

    1174 区间中最大的数 1.0 秒 131,072.0 KB 0 分 基础题   给出一个有N个数的序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,最大的数是多少. 例如: 1 ...

  4. P3865 【模板】ST表

    P3865 [模板]ST表 https://www.luogu.org/problemnew/show/P3865 题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数 ...

  5. Luogu P2880 [USACO07JAN]平衡的阵容Balanced Lineup (ST表模板)

    传送门(ST表裸题) ST表是一种很优雅的算法,用于求静态RMQ 数组l[i][j]表示从i开始,长度为2^j的序列中的最大值 注意事项: 1.核心部分: ; (<<j) <= n; ...

  6. POJ 3264 Balanced Lineup | st表

    题意: 求区间max-min st表模板 #include<cstdio> #include<algorithm> #include<cstring> #inclu ...

  7. 洛谷—— P3865 【模板】ST表

    https://www.luogu.org/problemnew/show/P3865 题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每 ...

  8. luogu P3865 【模板】ST表

    题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每次查询复杂度为 O(1)O(1) 题目描述 给定一个长度为 NN 的数列,和 MM 次询 ...

  9. 洛谷 P3865 【模板】ST表

    P3865 [模板]ST表 题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每次查询复杂度为 O(1)O(1) 题目描述 给定一个长度为  ...

随机推荐

  1. window.returnValue使用方法

    returnValue是javascript中html的window对象的属性,目的是返回窗口值,当用window.showModalDialog函数打开一个IE的模式窗口(模式窗口知道吧,就是打开后 ...

  2. 虚拟机中Ubuntu安装vmtools

    1.解压vmtools文件为VMWARETO.TGZ VMtools文件一般在系统桌面,如果没有可以点击左上方的"虚拟机-安装VMware Tools"即可出现在桌面,也可以通过U ...

  3. fflush - 刷新一个流

    SYNOPSIS 总览 #include <stdio.h> int fflush(FILE *stream); DESCRIPTION 描述 函数 fflush 强制在所给的输出流或更新 ...

  4. 自动生成 WebApi 在线说明文档。

    1.使用Swashbuckle实现 Swashbuckle 是.NET类库,可以将WebAPI所有开放的控制器方法生成对应SwaggerUI的JSON配置.再通过SwaggerUI 显示出来.类库中已 ...

  5. java编程基础——二叉树的镜像

    题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 题目代码 /** * @program: JavaCode * @description: 操作给定的二叉树,将其变换为源二叉树的镜像. * 二 ...

  6. 如何在Git提交空文件夹

    1,git clone url 拉取代码至本地 2,mkdir 文件夹名称 在本地创建文件夹 3,cd 文件夹名称 git init 初始化文件夹 vi .gitkeep 创建.gitkeep文件,内 ...

  7. Oracle 汇总函数

    汇总函数,也叫统计函数.聚合函数.分组函数 汇总函数必须跟 group by 语句一起使用,对数据进行分组汇总. ① 求和:sum(col).列必须是数值. ② 最小值:min(col).列可以是数值 ...

  8. JSPatch - iOS 动态补丁

    JSPatch库,支持在线更新iOS应用,目前BDN项目中有用到,主要用来修复线上Crash和Bug 相关博文推荐: JSPatch – 动态更新iOS APP(这是JSPatch作者的博文) JSP ...

  9. python2, 3环境变量配置(win10下)

    1.找到此电脑,右击点击属性 2.左边侧栏,高级系统设置 3.系统属性中点击高级 4.点击环境变量 5.可以看到 某某某用户变量和系统变量两个方框 其中,系统变量是要你在打开cmd是用管理员身份运行所 ...

  10. 《TensorFlow实战》中AlexNet卷积神经网络的训练中

    TensorFlow实战中AlexNet卷积神经网络的训练 01 出错 TypeError: as_default() missing 1 required positional argument: ...