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
思路:预处理第i的数在1~i中出现了多少次,得到freq[i],这样就转化为了对freq数组的RMQ了,即求max{freq[x~y]};但其实不是这样的,freq[x]中记录的频率可能要大于a[x]实际在区间[x,y]出现的次数,同理freq[y]也未必准确;
那我们就把区间[x,y]分成两段,一段是[x,t],一段是[t+1,y];t是与a[x]相等的最后一个元素的下标,那么答案即为max(t-x+1,max{freq[t+1~y]});
AC代码:
#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; int n,q; int a[100010]; int fre[100010]; int bl[100010];//a[x]所属区域,也可以不要该数组,则r[i]的含义就是a[i]出现的最后位置 int r[100010];//r[i]的含义是区域i的最右下标 int maxn[100010][20]; void ST(){ for(int i=1;i<=n;i++) maxn[i][0]=fre[i]; int k=int(log(n*1.0)/log(2.0)); for(int j=1;j<=k;j++){ for(int i=1;i<=n;i++){ if(i+(1<<j)-1>n) break; maxn[i][j]=max(maxn[i][j-1],maxn[i+(1<<(j-1))][j-1]); } } } int query(int x,int y){ int k=int(log(y-x+1.0)/log(2.0)); return max(maxn[x][k],maxn[y-(1<<k)+1][k]); } int main() { while(scanf("%d",&n)!=EOF&&n){ scanf("%d",&q); int cnt=0; scanf("%d",&a[1]),fre[1]=1,bl[1]=++cnt; for(int i=2;i<=n;i++) { scanf("%d",&a[i]); if(a[i]==a[i-1]) fre[i]=fre[i-1]+1,bl[i]=bl[i-1],r[bl[i]]=i; else fre[i]=1,bl[i]=++cnt,r[bl[i]]=i; } ST(); while(q--){ int x,y; scanf("%d%d",&x,&y); if(bl[x]==bl[y]) printf("%d ",y-x+1); else printf("%d ",max(r[bl[x]]-x+1,query(r[bl[x]]+1,y))); } } return 0; }