hdu 1806 Frequent values(给定一个非降序数组,求任意区间内出现次数最多的数的次数)
最后更新于:2022-04-01 16:02:08
**1.题目解析可见《训练指南》P198**
**2代码:**
~~~
#include<cstdio>
#include<cstring>
#include<cmath>
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define N 100005
#define INF 1<<30
using namespace std;
int a[N];
int value[N],cnt[N],num[N],L[N],R[N];
int ST[N][20];
int n,q;
int k;
void make_ST()//对cnt[]预处理
{
for(int i=1;i<=k;i++)
{
ST[i][0]=cnt[i];
}
for(int j=1;(1<<j)<=n;j++)
{
for(int i=1;(i+(1<<j)-1)<=n;i++)
{
ST[i][j]=Max(ST[i][j-1],ST[i+(1<<(j-1))][j-1]);
}
}
}
int Query(int l,int r)
{
if(l>r)
return 0;
else
{
int kk=floor(log2(r-l+1));
return Max(ST[l][kk],ST[r-(1<<kk)+1][kk]);
}
}
int main()
{
while(scanf("%d",&n)&&n)
{
scanf("%d",&q);
k=0;
value[0]=INF;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]!=value[k])
{
R[k]=i;
value[++k]=a[i];
L[k]=i-1;
cnt[k]=1;
num[i]=k;
}
else
{
cnt[k]++;
num[i]=num[i-1];
}
}
R[k]=n+1;
make_ST();
while(q--)
{
int l,r;
scanf("%d%d",&l,&r);
if(num[l]==num[r])
{
printf("%d\n",r-l+1);
}
else
{
int tmp=Max(R[num[l]]-l,r-L[num[r]]);
int ans=Max(tmp,Query(num[l]+1,num[r]-1));
printf("%d\n",ans);
}
}
}
return 0;
}
~~~