D. Frequent values
University of Ulm Local Contest
Problem F: Frequent values
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 Specification
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 Specification
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
解题:注意处理边界,我的d存出现次数,是从左往右的,故左边界很需要处理!而右边界就不需要处理了。因为左边界的左边一个元素正是我们选取区间的最优值可能算入了边界左边的与边界相等的数值。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <vector> 6 #include <climits> 7 #include <algorithm> 8 #include <cmath> 9 #define LL long long 10 using namespace std; 11 const int maxn = 100010; 12 int d[maxn],dt[maxn]; 13 struct node { 14 int lt,rt,val,index; 15 } tree[maxn<<2]; 16 void build(int lt,int rt,int v) { 17 tree[v].lt = lt; 18 tree[v].rt = rt; 19 if(lt == rt) { 20 tree[v].val = d[lt]; 21 tree[v].index = lt; 22 return; 23 } 24 int mid = (lt+rt)>>1; 25 build(lt,mid,v<<1); 26 build(mid+1,rt,v<<1|1); 27 if(tree[v<<1].val >= tree[v<<1|1].val) { 28 tree[v].val = tree[v<<1].val; 29 tree[v].index = tree[v<<1].index; 30 } else { 31 tree[v].val = tree[v<<1|1].val; 32 tree[v].index = tree[v<<1|1].index; 33 } 34 tree[v].val = max(tree[v<<1].val,tree[v<<1|1].val); 35 } 36 int query(int &index,int lt,int rt,int v) { 37 if(tree[v].lt == lt && tree[v].rt == rt) { 38 index = tree[v].index; 39 return tree[v].val; 40 }; 41 int mid = (tree[v].lt+tree[v].rt)>>1; 42 int a,b,x,y; 43 if(rt <= mid) return query(index,lt,rt,v<<1); 44 else if(lt > mid) return query(index,lt,rt,v<<1|1); 45 else { 46 x = query(a,lt,mid,v<<1); 47 y = query(b,mid+1,rt,v<<1|1); 48 if(x >= y) { 49 index = a; 50 return x; 51 } else { 52 index = b; 53 return y; 54 } 55 } 56 } 57 int main() { 58 int n,m,i,x,y,temp,a,b,index,j; 59 while(scanf("%d",&n),n) { 60 scanf("%d",&m); 61 for(i = 1; i <= n; i++) 62 scanf("%d",dt+i); 63 temp = d[1] = 1; 64 for(i = 2; i <= n; i++) { 65 if(dt[i] == dt[i-1]) temp++; 66 else temp = 1; 67 d[i] = temp; 68 } 69 build(1,n,1); 70 for(i = 0; i < m; i++) { 71 scanf("%d %d",&x,&y); 72 temp = query(index,x,y,1); 73 if(dt[x] == dt[y]) printf("%d ",y-x+1); 74 else if(x == 1 || dt[index] != dt[x-1]) printf("%d ",temp); 75 else { 76 for(j = x+1; dt[j] == dt[j-1] && j <= y; j++); 77 temp = query(index,j,y,1); 78 printf("%d ",max(j-x,temp)); 79 } 80 } 81 } 82 return 0; 83 }
RMQ
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <climits> 7 #include <vector> 8 #include <queue> 9 #include <cstdlib> 10 #include <string> 11 #include <set> 12 #include <stack> 13 #define LL long long 14 #define pii pair<int,int> 15 #define INF 0x3f3f3f3f 16 using namespace std; 17 const int maxn = 100010; 18 int a[maxn],b[maxn],c[maxn][20],n,m,s,t; 19 int main() { 20 while(scanf("%d",&n),n){ 21 scanf("%d",&m); 22 for(int i = 0; i < n; i++) 23 scanf("%d",b+i); 24 int tmp = 1; 25 a[n-1] = tmp; 26 for(int i = n-2; i >= 0; i--){ 27 if(b[i] == b[i+1]) ++tmp; 28 else tmp = 1; 29 a[i] = tmp; 30 } 31 for(int i = n-1; i >= 0; --i){ 32 c[i][0] = a[i]; 33 for(int j = 1; i + (1<<j) <= n; ++j) 34 c[i][j] = max(c[i][j-1],c[i+(1<<(j-1))][j-1]); 35 } 36 while(m--){ 37 scanf("%d %d",&s,&t); 38 --s; 39 --t; 40 tmp = lower_bound(b+s,b+t+1,b[t]) - b; 41 int ans = t - tmp + 1; 42 t = tmp - 1; 43 int r = log2(t - s + 1.0); 44 if(t <= s) printf("%d ",ans); 45 else printf("%d ",max(ans,max(c[s][r],c[t-(1<<r)+1][r]))); 46 } 47 } 48 return 0; 49 }