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
思路:计算区间的相同个数,然后定个左右边界点,外加一个简单的RMQ。
#include<iostream> #include<cstring> #include<cstdio> #define FOR(i,a,b) for(int i=a;i<=b;++i) #define clr(f,z) memset(f,z,sizeof(f)) #define ll(x) (1<<x) using namespace std; const int mm=100000+9; int N,Q; int f[mm],L[mm],R[mm]; int rmq[mm][33],bit[mm]; void initRMQ() { bit[0]=-1; FOR(i,1,mm-1)bit[i]=(i&(i-1))==0?bit[i-1]+1:bit[i-1]; FOR(i,1,N)rmq[i][0]=f[i]; FOR(i,1,bit[N]) for(int j=1;j+ll(i)-1<=N;++j) rmq[j][i]=max(rmq[j][i-1],rmq[j+ll(i-1)][i-1]); } int RMQ(int l,int r) { if(l>r)return 0; int t=bit[r-l+1]; r-=ll(t)-1; return max(rmq[l][t],rmq[r][t]); } int main() { int a,b; while(scanf("%d",&N)&&N) { scanf("%d",&Q); f[0]=mm;f[N+1]=mm; FOR(i,1,N) { scanf("%d",&f[i]); } int z=0,zs=f[1],kai=1; FOR(i,1,N+1) { if(f[i]!=zs) { for(int j=i-1;f[j]==zs;--j) f[j]=z,L[j]=kai,R[j]=i-1; kai=i;z=1;zs=f[i]; } else ++z; } initRMQ(); while(Q--) { scanf("%d%d",&a,&b); int ans; if(R[a]>L[b])ans=b-a+1; else ans=max(R[a]-a+1,b-L[b]+1); ans=max(ans,RMQ(R[a]+1,L[b]-1)); printf("%d\n",ans); } } }