POJ-3368-Frequent values

因为今天刚好看到RMQ,就做了一下,结果折腾了一晚上。

关于RMQ其实相当于是模板,关键是建立模型以及后面有几种特殊的情况需要特殊处理,我因为在最后一种情况写错了,WA了很久。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#define MAX 100010
using namespace std;
int n,m,cou,a[MAX],num[MAX];
int l[MAX],r[MAX],val[MAX],count[MAX],d[MAX][50];
void RMQ_Init()
{
    for(int i=1;i<=cou;i++)
	d[i][0]=count[i];
    for(int j=1;(1<<j)<=cou;j++)
	for(int i=1;i+j-1<=cou;i++)
	    d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
}
int RMQ(int l,int r)
{
    int k=0;
    while((1<<(k+1))<=r-l+1)k++;
    return max(d[l][k],d[r-(1<<k)+1][k]);
}
int main()
{
    while(scanf("%d",&n)&&n)
    {
	scanf("%d",&m);
	scanf("%d",&a[1]);
	memset(count,0,sizeof(count));
	memset(d,0,sizeof(d));
	cou=1;
	val[cou]=a[1];
	l[cou]=1;
	r[cou]=1;
	count[cou]=1;
	num[1]=cou;
	for(int i=2;i<=n;i++)
	{
	    scanf("%d",&a[i]);
	    if(a[i]!=a[i-1])
	    {
		r[cou]=i-1;
		cou++;
		val[cou]=a[i];
		l[cou]=i;
	    }
	    count[cou]++;
	    num[i]=cou;
	}
	r[cou]=n;
	RMQ_Init();
	for(int i=0;i<m;i++)
	{
	    int cl,cr;
	    scanf("%d%d",&cl,&cr);
	    if(num[cl]==num[cr])
	    {
		printf("%d\n",cr-cl+1);
		continue;
	    }
	    int ans=max(r[num[cl]]-cl+1,cr-l[num[cr]]+1);
	    if(num[cl]+1==num[cr])
	    {
		printf("%d\n",ans);
		continue;
	    }
	    ans=max(ans,RMQ(num[cl]+1,num[cr]-1));
	    printf("%d\n",ans);
	}
    }
    return 0;
}


你可能感兴趣的:(RMQ)