POJ 3368 Frequent values 解题报告
Time Limit: 2000MS | Memory Limit: 65536KB | 64bit IO Format: %lld & %llu |
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 andj (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
1 2 3 4 5 6 |
10 3 -1 -1 1 1 1 1 3 10 10 10 2 3 1 10 5 10 0 |
Sample Output
1 2 3 |
1 4 3 |
Source
题目大意为给出一个n个数的不下降数列,然后有q个询问,求给定区间内出现最多的数的次数。由于数列是不下降的,相同的数必然挨在一起,这个数列边自然分成了若干块,并且每块中的数都相等。令f[n]为第n个数在块中的编号,如样例f[1]=1, f[2]=2, f[3]=1, f[4]=2, f[5]=3……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include <cstdio> #include <algorithm> using namespace std; const int maxn = 100000 + 10; int a[maxn], f[maxn]; int dp[maxn][20], mm[maxn]; void initrmq(int n, int b[]) { mm[0] = -1; for (int i = 1; i <= n; i++) { mm[i] = ((i & (i - 1)) == 0) ? mm[i - 1] + 1 : mm[i - 1]; dp[i][0] = b[i]; } for (int j = 1; j <= mm[n]; j++) for (int i = 1; i + (1 << j) - 1 <= n; i++) dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]); } int rmq(int x, int y) { int k = mm[y - x + 1]; return max(dp[x][k], dp[y - (1 << k) + 1][k]); } int main() { int n, q; while (scanf("%d%d", &n, &q) == 2) { for (int i = 1; i <= n; i++) scanf("%d", &a[i]); int l, r; f[1] = 1; for (int i = 2; i <= n; i++) f[i] = (a[i] == a[i - 1]) ? f[i - 1] + 1 : 1; initrmq(n, f); while (q--) { scanf("%d%d", &l, &r); int tmp = 0, pos = l; while (pos <= r && a[pos] == a[pos - 1]) pos++, tmp++; printf("%d\n", max(tmp, rmq(pos, r))); } } return 0; } |
来一发吐槽