传送门: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:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <cmath> 5 #define INF 0x3f3f3f3f 6 using namespace std; 7 const int MAXN = 1e5+10; 8 9 int num[MAXN]; 10 int hh[MAXN]; 11 int L[MAXN], R[MAXN]; 12 int b[MAXN]; 13 int dpmax[MAXN][20]; 14 int mm[MAXN]; 15 16 void init_RMQ(int N, int a[]) 17 { 18 mm[0] = -1; 19 for(int i = 1; i <= N; i++){ 20 mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1]; 21 dpmax[i][0] = b[i]; 22 } 23 for(int ilen = 1; ilen <= mm[N]; ilen++){ 24 for(int i = 1; i+(1<<ilen)-1 <= N; i++) 25 dpmax[i][ilen] = max(dpmax[i][ilen-1], dpmax[i+(1<<(ilen-1))][ilen-1]); 26 } 27 } 28 29 int get_RMQ(int LL, int RR) 30 { 31 int k = mm[RR-LL+1]; 32 return max(dpmax[LL][k], dpmax[RR-(1<<k)+1][k]); 33 } 34 35 int main() 36 { 37 int N, M; 38 while(~scanf("%d", &N) && N){ 39 scanf("%d", &M); 40 for(int i = 1; i <= N; i++){ 41 scanf("%d", &num[i]); 42 } 43 44 int k = 1, ll = 1; 45 memset(b, 0 ,sizeof(b)); 46 47 for(int i = 1; i <= N; i++){ 48 if(i > 1 && num[i] != num[i-1]){ 49 for(int j = ll; j < i; j++){ 50 L[j] = ll; 51 R[j] = i-1; 52 } 53 b[k] = i-ll; 54 ll = i; 55 k++; 56 } 57 hh[i] = k; 58 } 59 60 for(int j = ll; j <= N; j++){ 61 L[j] = ll; 62 R[j] = N; 63 } 64 b[k] = N-ll+1; 65 init_RMQ(k, b); 66 67 int U, V; 68 while(M--){ 69 scanf("%d%d", &U, &V); 70 int st = hh[U], ed = hh[V]; 71 if(st == ed){ 72 printf("%d\n", V-U+1); 73 continue; 74 } 75 int ans = max(R[U]-U+1, V-L[V]+1); 76 st++, ed--; 77 if(st <= ed) ans = max(ans, get_RMQ(st, ed)); 78 printf("%d\n", ans); 79 } 80 } 81 return 0; 82 }