题目链接

题目

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. ADS主要仿真器介绍

    ADS主要仿真器介绍        ADS ( Advanced Design System ) 是美国Agilent公司推出的电路和系统分析软件,它集成多种仿真软件的优点,仿真手段丰富多样,可实现包 ...

  2. 汶川大地震中的SAP成都研究院

    5·12汶川地震,发生于北京时间(UTC+8)2008年5月12日(星期一)14时28分04秒,此次地震的面波震级 里氏震级达8.0Ms.矩震级达8.3Mw,地震烈度达到11度.地震波及大半个中国及亚 ...

  3. Aizu 2301 Sleeping Time(概率,剪枝)

    根据概率公式dfs即可,判断和区间[T-E,T+E]是否有交,控制层数. #include<bits/stdc++.h> using namespace std; int K,R,L; d ...

  4. Eureka 微服务注册中心搭建

    本机IP为  192.168.1.102 1.   新建Maven项目   eureka 2.   pom.xml <project xmlns="http://maven.apach ...

  5. VC-基础-WebBrowser控件中弹出新网页窗口

    用webbrowser控件浏览网页时,常弹出新的网页窗口,若不做任何控制的话,会在默认浏览器(一般是IE)中打开,这样就在新的窗口打开了,原程序就很难控制了,且存在webbrowser控件和IE的se ...

  6. BeyondCompare:如何之比较文件内容的不同?

    问题描述: 在使用beyond compare比较文件的时候,常会有很多不同,但是点击打开后,发现内容没有不同.这个是因为工具把文件的日期.大小等非内容因素也比较了进去. 解决方法: 点击“会话” - ...

  7. js浮点数加减乘除

    浮点数精确计算 /** ** 加法函数,用来得到精确的加法结果 ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显.这个函数返回较为精确的加法结果. ** 调用:ac ...

  8. JS的四舍五入问题

    最近踩了一个坑,mark一下toFixed四舍五入问题,详见代码: var myFixed = function(num, fix) { num = (parseFloat(num) * + ) / ...

  9. 解决cmd目录下pip命令不存在的问题

    解决cmd目录下pip命令不存在的问题 注:pip.exe程序在Python安装目录下的scripts中1.在cmd命令中输入: 先输入:python -m ensurepip 再输入:python ...

  10. 【python学习】新手基础程序练习(二)

    Ι 继续上一节得内容,这里主要是对各种知识的理解以及如何运用. 一.执行 Python 脚本的两种方式 1.把python执行文件加到计算机的环境变量中,然后新建文件把程序写在新文件里,再通过cmd命 ...