POJ 3368 Frequent values 【ST表RMQ 维护区间频率最大值】
传送门:http://poj.org/problem?id=3368
| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 23016 | Accepted: 8060 |
Description
You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several queries consisting of indices i and j (1 ≤ i ≤ j ≤ n). For each query, determine the most frequent value among the integers ai , ... , aj.
Input
The input consists of several test cases. Each test case starts with a line containing two integers n and q (1 ≤ n, q ≤ 100000). The next line contains n integers a1 , ... , an (-100000 ≤ ai ≤ 100000, for each i ∈ {1, ..., n}) separated by spaces. You can assume that for each i ∈ {1, ..., n-1}: ai ≤ ai+1. The following q lines contain one query each, consisting of two integers i and j (1 ≤ i ≤ j ≤ n), which indicate the boundary indices for the
query.
The last test case is followed by a line containing a single 0.
Output
For each query, print one line with one integer: The number of occurrences of the most frequent value within the given range.
Sample Input
10 3
-1 -1 1 1 1 1 3 10 10 10
2 3
1 10
5 10
0
Sample Output
1
4
3
Source
题意概括:
给出一串长度为 N 的非递减序列,和 M 次查询, 每次查询区间 【L,R】的出现频率最高的数的频率。
解题思路:
很妙的一种做法啊!
因为他是非递减数列 ,所以基于把每一个连续的相同的数作为同一块处理。
那么我们可以把查询区间分成两部分来处理。
第一部分:边界块,区间 起点 L 所处的块 和 区间 R 所处的块。
如果两者所处的块相同则说明,该区间在一个块内,区间内的数都相同,那么我们所求的最大频率就是当前区间长度了
如果两者所处的块不相同,那么说明除了这两个块还有其他的块,那么剩下的那些块就是接下来讨论的第二部分。
第二部分:很显然剩余的块都是连续的,完整的。那么RMQ维护的区间最大值妥妥的,没毛病(这里的最大值就是预处理的每一块的数出现的频率啦)。
AC code:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#define INF 0x3f3f3f3f
using namespace std;
const int MAXN = 1e5+; int num[MAXN];
int hh[MAXN];
int L[MAXN], R[MAXN];
int b[MAXN];
int dpmax[MAXN][];
int mm[MAXN]; void init_RMQ(int N, int a[])
{
mm[] = -;
for(int i = ; i <= N; i++){
mm[i] = ((i&(i-)) == )?mm[i-]+:mm[i-];
dpmax[i][] = b[i];
}
for(int ilen = ; ilen <= mm[N]; ilen++){
for(int i = ; i+(<<ilen)- <= N; i++)
dpmax[i][ilen] = max(dpmax[i][ilen-], dpmax[i+(<<(ilen-))][ilen-]);
}
} int get_RMQ(int LL, int RR)
{
int k = mm[RR-LL+];
return max(dpmax[LL][k], dpmax[RR-(<<k)+][k]);
} int main()
{
int N, M;
while(~scanf("%d", &N) && N){
scanf("%d", &M);
for(int i = ; i <= N; i++){
scanf("%d", &num[i]);
} int k = , ll = ;
memset(b, ,sizeof(b)); for(int i = ; i <= N; i++){
if(i > && num[i] != num[i-]){
for(int j = ll; j < i; j++){
L[j] = ll;
R[j] = i-;
}
b[k] = i-ll;
ll = i;
k++;
}
hh[i] = k;
} for(int j = ll; j <= N; j++){
L[j] = ll;
R[j] = N;
}
b[k] = N-ll+;
init_RMQ(k, b); int U, V;
while(M--){
scanf("%d%d", &U, &V);
int st = hh[U], ed = hh[V];
if(st == ed){
printf("%d\n", V-U+);
continue;
}
int ans = max(R[U]-U+, V-L[V]+);
st++, ed--;
if(st <= ed) ans = max(ans, get_RMQ(st, ed));
printf("%d\n", ans);
}
}
return ;
}
POJ 3368 Frequent values 【ST表RMQ 维护区间频率最大值】的更多相关文章
- poj 3368 Frequent values(经典)【RMQ】
<题目链接> 题目大意: 给你一个长度为n的序列,这个序列每个数都有一个值,接下来进行q次询问,问在指定区间内出现次数最多的数出现了几次. 解题分析: 因为该序列是非降序的,所以该序列中的 ...
- POJ 3368 Frequent values RMQ ST算法/线段树
Frequent values Time Limit: 2000MS Memory Lim ...
- POJ 3368 Frequent values (基础RMQ)
Frequent values Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14742 Accepted: 5354 ...
- poj 3368 Frequent values(RMQ)
/************************************************************ 题目: Frequent values(poj 3368) 链接: http ...
- POJ 3368.Frequent values-处理数据+RMQ(ST)
昨天写的博客删了,占坑失败,还是先把RMQ玩的6一点再去搞后面的东西.废话少说,题解题姐姐_(:з」∠)_ Frequent values Time Limit: 2000MS Memo ...
- Poj 3368 Frequent values
/* 线段树区间合并 维护几个信息 到时候乱搞一下就好了 开始T了 有一种情况可以不用递归 直接算出来 */ #include<iostream> #include<cstdio&g ...
- poj 3368 Frequent values(段树)
Frequent values Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13516 Accepted: 4971 ...
- POJ 3368 Frequent values(RMQ 求区间出现最多次数的数字的次数)
题目链接:http://poj.org/problem? id=3368 Description You are given a sequence of n integers a1 , a2 , .. ...
- poj 3368 Frequent values(RMQ)
题目:http://poj.org/problem?id=3368 题意:给定n个数,顺序为非下降,询问某个区间内的数出现最多的数的 出现次数.. 大白书上的 例题..算是RMQ变形了, 对 原数组重 ...
随机推荐
- Firebird 条件函数
1.iif IIF (<condition>, ResultT, ResultF) 示例: select iif( sex = 'M', 'Sir', 'Madam' ) from Cu ...
- C# 处理XML的基本操作
文章部分代码引用参考文章, 文末参考文章已标注 ,本篇文章建立在两篇参考文章基础上,可以先阅读参考文章 XML 相关类 XDocument XmlDocument XmlReader XmlWrit ...
- javascript bind在回调中精简匿名函数的用法
常规写法: Promise对象回调,匿名函数调用其他方法 更精简的写法: 注:这种写法的使用有两个严苛的限制. 1.回调的结果必须放在实际调用方法参数的最后一位: 2.回调函数中只调用其他一个方法.
- Web开发:Bootstrap的应用
- 中南oj 1213: 二叉树结点公共祖先
1213: 二叉树结点公共祖先 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 159 Solved: 87 [Submit][Status][Web ...
- 如何将一个SpringBoot简便地打成一个war包(转)
为什么要把SpringBoot打成war包 正常情况下SpringBoot项目是以jar包的形式,通过命令行: java -jar demo.jar 来运行的,并且SpringBoot是内嵌Tomca ...
- 介绍一款小众的IDE
作为前端工程师的你们平时主要使用什么IDE,atom.webstorm.sublime还是vscode? 今天介绍一款比较小众的IDE,Adobe的开源项目Brackets,提供Windows和OS ...
- iis添加共享目录为虚拟目录
注意物理路径处不能直接选择映射成的本地盘符!!!
- js计算时间差(天,小时,分钟,秒)
<script type="text/javascript"> var date1= '2015/05/01 00:00:00'; //开始时间 var date2 = ...
- Oracle使用超大SQL脚本文件恢复数据问题记录
在以前获取的Oracle数据库备份一般都是dmp文件,创建表空间和用户就直接使用imp或者impdp导入即可. 这一次遇到的情况比较特殊,对方提供数据时给我的是使用SQLPlus导出的SQL脚本文件, ...