POJ 3368 Frequent values 【ST表RMQ 維護區間頻率最大值】
傳送門:http://poj.org/problem?id=3368
Frequent valuesTime Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 23016 | Accepted: 8060 |
Description
You are given a sequence of n integers a1
Input
The input consists of several test cases. Each test case starts with a line containing two integers n
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
Ulm Local 2007
題意概括:
給出一串長度為 N 的非遞減序列,和 M 次查詢, 每次查詢區間 【L,R】的出現頻率最高的數的頻率。
解題思路:
很妙的一種做法啊!
因為他是非遞減數列 ,所以基於把每一個連續的相同的數作為同一塊處理。
那麼我們可以把查詢區間分成兩部分來處理。
第一部分:邊界塊,區間 起點 L 所處的塊 和 區間 R 所處的塊。
如果兩者所處的塊相同則說明,該區間在一個塊內,區間內的數都相同,那麼我們所求的最大頻率就是當前區間長度了
如果兩者所處的塊不相同,那麼說明除了這兩個塊還有其他的塊,那麼剩下的那些塊就是接下來討論的第二部分。
第二部分:很顯然剩餘的塊都是連續的,完整的。那麼RMQ維護的區間最大值妥妥的,沒毛病(這裡的最大值就是預處理的每一塊的數出現的頻率啦)。
AC code:
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 }View Code