题目链接

题目

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. Mvc重写JsonResult

    用了mvc有一段时间了,慢慢的熟悉起来了,也渐渐的发现了mvc的一些缺点,比如当我们返回 Json(new{})的时候没办法做到将首字母转换成小写.日期再序列化过后是时间戳需要到前台重新处理或者提在在 ...

  2. webpack最简单的入门教程里bundle.js之运行单步调试的原理解析

    读这篇文章的朋友,请确保对webpack有最基础的认识. 您可以阅读我前一篇文章:Webpack 10分钟入门 来在本地运行一个Webpack的hello world项目.https://www.to ...

  3. java的图形界面初学惯用

    1.单一界面的创建 public void mainFrame() { HashMap<String, Component> views = new HashMap<String, ...

  4. IOS 强指针(strong)和弱指针(weak)

    // strong 强指针        // weak 弱指针        // ARC, 只要对象没有强指针就会自动释放        // OC中默认都是强指针

  5. 2019年5~6月训练记录(更新ing)

    前言 \(ZJOI\)正式结束了. 但期中考试只考了年级\(216\),退役既视感... 于是就被抓回去补文化课了. 下半个学期可能要以文化课为主了吧! 但周三.周日应该还是会正常参加训练的,但其他时 ...

  6. 倍增LCA

    前言 在做树上问题时,我们经常会遇到 \(LCA\)(最近公共祖先)问题.曾经的我遇到这类问题只会\(O(n)\)暴力求解,学了倍增\(LCA\),就可以\(O(logn)\)解决了. 简介 倍增\( ...

  7. python_59_装饰器2

    #匿名函数,无函数名 calc=lambda x:x*3 print(calc(3)) sum=lambda x,y,z:x+y+z print(sum(1,2,3)) ''' 高阶函数 a:把一个函 ...

  8. nginx installl

    参考http://jingyan.baidu.com/album/4b07be3cbbb54848b380f322.html?picindex=5 安装nginx需要的依赖包 wget 下载 编译安装 ...

  9. React后台管理系统-后台接口封装

    1新建文件夹 service ,里边建4个文件,分别是statistic-service.jsx 首页数据统计接口, user-service.jsx用户接口, product-service.jsx ...

  10. cf492E. Vanya and Field(扩展欧几里得)

    题意 $n \times n$的网格,有$m$个苹果树,选择一个点出发,每次增加一个偏移量$(dx, dy)$,最大化经过的苹果树的数量 Sol 上面那个互素一开始没看见,然后就GG了 很显然,若$n ...