poj Frequent values 3368
来源:互联网 发布:福州锐捷网络招聘 编辑:程序博客网 时间:2024/06/02 06:14
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 102 31 105 100
这个题我是被自己感动到了,没想到自己做的第二个RMQ的题可以一次就过,编译也是一次过,太感动了!
哈哈!
题意是:给出一个非降序的整数数组,你的任务是对于一系列询问,回答区间内出现最多的值的次数
说一下如何做
正如《算法竞赛入门经典(训练指南)》198页讲的,
这里我们因为是按非降序排列的,那也就是说相同的数字一定是在一起的
这里我们就用相同的数字为一段来描述
那么说例题中我们就有2 4 1 3分别代表四段
我们用a[]数组来存给出的值,
下面说说我们用到的数组的意义
value[]: 代表第i段的具体数值
coun[]: 代表第i段出现的次数
lef[] : 代表第i段的左端点的位置
righ[]: : 代表第i段的右端点的位置
num[] 数组稍有不同 他指的是第p个位置上为第几段
这样我们只要找num[L]+1, num[R]-1段中的最大值与righ[L]-L+1, R-lef[R]+1,三个中的最大值就可以了,
当然特殊情况也要有考虑
大致可分为三种:
代码如下:
#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>using namespace std;const int inf = INT_MAX;int value[300005], coun[300005];int num[300005], lef[300005], righ[300005];int a[300005], b[300005][20];int top;void inti(){ a[0] = inf; top = 0;}void RMQ(){ int i, j; for ( i = 1;i <= top; i++ ) b[i][0] = coun[i]; for ( j = 1;(1<<j) <= top; j++ ) { for ( i = 1;i+(1<<(j-1)) <= top; i++ ) b[i][j] = max(b[i][j-1], b[i+(1<<(j-1))][j-1]); }}int RMQ_check(int y, int x){ int nb = 0; while ( (1<<nb) <= y-x+1 ) nb++; return max(b[y-(1<<(nb-1))+1][nb-1], b[x][nb-1]);}int main(){ int i, n, m; int L, R; while ( ~scanf ( "%d", &n )&&n != 0 ) { scanf ( "%d", &m ); inti(); for ( i = 1;i <= n; i++ ) { scanf ( "%d", &a[i] ); if ( a[i] != a[i-1] ) { righ[top] = i-1; top++; lef[top] = i; value[top] = a[i]; coun[top] = 0; } num[i] = top; coun[top]++; } righ[top] = n; RMQ(); for ( i = 0;i < m; i++ ) { scanf ( "%d %d", &L, &R ); if ( num[L] == num[R] ) printf ( "%d\n", R-L+1 ); else if ( num[R]-num[L] == 1 ) printf ( "%d\n", max(righ[num[L]]-L+1, R-lef[num[R]]+1) ); else { int ma1 = righ[num[L]]-L+1; int ma2 = R-lef[num[R]]+1; int ma3 = RMQ_check(num[R]-1, num[L]+1); printf ( "%d\n", max(ma1, max(ma2, ma3))); } } } return 0;}
代码菜鸟,如有错误,请多包涵!!!
如有帮助记得支持我一下,谢谢!!!
- POJ 3368 Frequent values
- poj 3368 Frequent values
- POJ 3368 Frequent Values
- poj 3368 Frequent values
- poj 3368 Frequent values
- poj 3368 Frequent values
- POJ-3368-Frequent values
- poj 3368 Frequent values
- poj 3368 Frequent values
- POJ 3368: Frequent values
- Poj 3368 Frequent values
- POJ 3368 Frequent values
- poj 3368 Frequent values
- POJ 3368 Frequent values
- POJ 3368 Frequent values
- POJ 3368 Frequent values
- POJ 3368--Frequent values
- Poj 3368 Frequent values
- Android编程_创建和删除文件夹和文件
- java并发编程---synchronized和lock两种锁的比较
- 字符串subString方法的使用
- 简单的滑动冲突处理
- 解决“Dynamic Web Module 3.0 requires Java 1.6 or newer.”错误
- poj Frequent values 3368
- 监听是否点击了home键将客户端推到后台
- java 字符串问题
- it好博客
- aliyun阿里云Maven仓库地址——加速你的maven构建
- sp<> 强指针类的用法
- RxBus使用总结
- JavaScript编写城市联动框和时间联动框
- 解决plsql导入后中文乱码