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. Note: A naive algorithm may not run in time!
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
以相同的数值作为一个块
sum的空间大小是cnt 其他的空间大小都是n
num[i] 意思是a[i]这个数是属于第几个块
lef是a[i]的左边界 rig同理
dp里面存每个块的最大长度
注意边界处理 》》查询l r时 a[l] a[r]的数不要查 查lr范围内的 也就是开区间的内容
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define maxn 100500
#define inf 0x3f3f3f3f
#define clr(a,b) memset(a,b,sizeof(a));
using namespace std;
int lef[maxn],rig[maxn],a[maxn],num[maxn],dp[maxn][64],sum[maxn],cnt;
//rig and lef of range are like a lenth.
void rmq_init()
{
for(int i=1;i<=cnt;i++)
{
dp[i][0]=sum[i];
}
for(int j=1;(1<<j)<=cnt;j++)
{
for(int i=1;i+(1<<j)-1<=cnt;i++)
{
dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
}
/*for(int i=1;i<=cnt;i++)
{
for(int j=1;j<=cnt;j++)
cout<<dp[i][j]<<'\t';
cout<<endl;
}*/
}
int rmqq(int l,int r)
{
int k=0;
while(1<<k <=r-l+1) k++;
k--;
int ans=0;
ans=max(dp[l][k],dp[r-(1<<k)+1][k]);//区间可能有重合 保证了结果的正确性
return ans;
}
int main()
{
int n,q;
while(cin>>n&&n)
{
clr(sum,0)
cnt=0;
cin>>q;
a[0]=inf;
for(int i=1;i<=n;i++)
{
cin>>a[i];
num[i]=(a[i]==a[i-1])?cnt:++cnt;
sum[cnt]++;
if(a[i]==a[i-1]) lef[i]=lef[i-1];
else lef[i]=i;
}
rig[n]=n;
for(int i=n-1;i>=1;i--)
{
if(a[i]==a[i+1]) rig[i]=rig[i+1];
else rig[i]=i;
}
rmq_init();
while(q--)
{
int l,r;
cin>>l>>r;
if(num[l]==num[r])
{
cout<<r-l+1<<endl;
continue;
}
int inx=num[l]+1;
int iny=num[r]-1;
int in=rmqq(inx,iny);
int ans=max(max((rig[l]-l+1),(r-lef[r]+1)),in);
cout<<ans<<endl;
}
}
return 0;
}