CSU-2221 假装是区间众数(ST表模版题)
题目链接
题目
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表模版题)的更多相关文章
- $ST表刷题记录$
\(st表的题目不太多\) 我做过的就这些吧. https://www.luogu.org/problemnew/show/P3865 https://www.luogu.org/problemnew ...
- hdu5443 ST表裸题:求区间最大
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #d ...
- 51nod(1174 区间中最大的数)(ST表模板题)
1174 区间中最大的数 1.0 秒 131,072.0 KB 0 分 基础题 给出一个有N个数的序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,最大的数是多少. 例如: 1 ...
- P3865 【模板】ST表
P3865 [模板]ST表 https://www.luogu.org/problemnew/show/P3865 题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数 ...
- Luogu P2880 [USACO07JAN]平衡的阵容Balanced Lineup (ST表模板)
传送门(ST表裸题) ST表是一种很优雅的算法,用于求静态RMQ 数组l[i][j]表示从i开始,长度为2^j的序列中的最大值 注意事项: 1.核心部分: ; (<<j) <= n; ...
- POJ 3264 Balanced Lineup | st表
题意: 求区间max-min st表模板 #include<cstdio> #include<algorithm> #include<cstring> #inclu ...
- 洛谷—— P3865 【模板】ST表
https://www.luogu.org/problemnew/show/P3865 题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每 ...
- luogu P3865 【模板】ST表
题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每次查询复杂度为 O(1)O(1) 题目描述 给定一个长度为 NN 的数列,和 MM 次询 ...
- 洛谷 P3865 【模板】ST表
P3865 [模板]ST表 题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每次查询复杂度为 O(1)O(1) 题目描述 给定一个长度为 ...
随机推荐
- ADS主要仿真器介绍
ADS主要仿真器介绍 ADS ( Advanced Design System ) 是美国Agilent公司推出的电路和系统分析软件,它集成多种仿真软件的优点,仿真手段丰富多样,可实现包 ...
- 汶川大地震中的SAP成都研究院
5·12汶川地震,发生于北京时间(UTC+8)2008年5月12日(星期一)14时28分04秒,此次地震的面波震级 里氏震级达8.0Ms.矩震级达8.3Mw,地震烈度达到11度.地震波及大半个中国及亚 ...
- Aizu 2301 Sleeping Time(概率,剪枝)
根据概率公式dfs即可,判断和区间[T-E,T+E]是否有交,控制层数. #include<bits/stdc++.h> using namespace std; int K,R,L; d ...
- Eureka 微服务注册中心搭建
本机IP为 192.168.1.102 1. 新建Maven项目 eureka 2. pom.xml <project xmlns="http://maven.apach ...
- VC-基础-WebBrowser控件中弹出新网页窗口
用webbrowser控件浏览网页时,常弹出新的网页窗口,若不做任何控制的话,会在默认浏览器(一般是IE)中打开,这样就在新的窗口打开了,原程序就很难控制了,且存在webbrowser控件和IE的se ...
- BeyondCompare:如何之比较文件内容的不同?
问题描述: 在使用beyond compare比较文件的时候,常会有很多不同,但是点击打开后,发现内容没有不同.这个是因为工具把文件的日期.大小等非内容因素也比较了进去. 解决方法: 点击“会话” - ...
- js浮点数加减乘除
浮点数精确计算 /** ** 加法函数,用来得到精确的加法结果 ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显.这个函数返回较为精确的加法结果. ** 调用:ac ...
- JS的四舍五入问题
最近踩了一个坑,mark一下toFixed四舍五入问题,详见代码: var myFixed = function(num, fix) { num = (parseFloat(num) * + ) / ...
- 解决cmd目录下pip命令不存在的问题
解决cmd目录下pip命令不存在的问题 注:pip.exe程序在Python安装目录下的scripts中1.在cmd命令中输入: 先输入:python -m ensurepip 再输入:python ...
- 【python学习】新手基础程序练习(二)
Ι 继续上一节得内容,这里主要是对各种知识的理解以及如何运用. 一.执行 Python 脚本的两种方式 1.把python执行文件加到计算机的环境变量中,然后新建文件把程序写在新文件里,再通过cmd命 ...