POJ 3368 Frequent values【RMQ变形】

题目: http://poj.org/problem?id=3368

分析:将原序列转换一下
if(num[i]==num[i-1])
     f[i]=f[i-1]+1;
else
     f[i]++;
对于每个询问(l,r),分为两个部分,前半部分求与l之前相同的数的个数直到t,后半部分从t开始直接用RMQ求解最大值就行了。

最后结果为max(前半部分,后半部分)。

【若直接求(l,r)最大则错,若-1,-1,1.求[2,3] 】

#include <stdio.h>			
#include <math.h>
#define MIN 20
#define MAX 100050
int n;
int arr[MAX],maxdp[MAX][MIN]; 	
int a[MAX];

int max_m(int a,int b)
{
	return a>b?a:b;
}

void ST()
{			
	int i,j,t;
    for (i = 1; i <= n; i++)
        maxdp[i][0] = arr[i];
    for (j = 1; (1<<j) <= n; j++)
        for (i = 1; i+(1<<j)-1 <= n; i++)
		{
			t = i + ( 1 << (j-1) );
          	maxdp[i][j] = max_m(maxdp[i][j-1],maxdp[t][j-1]);
		}
}

int Query(int l,int r)
{			
    int k = (int)(log(r-l+1.0)/log(2.0));
	if(l>r) return 0;				//至关重要
	return max_m(maxdp[l][k],maxdp[r-(1<<k)+1][k]);
}


int main()
{
    int i,j,k,t,res,temp,ant;
	int Query(int x,int y);					
	while(scanf("%d",&n)&& n)
	{
		scanf("%d",&t);
		for (i = 1; i <= n; i++)
		{
			scanf("%d",&a[i]);
			if(i == 1)
				arr[i] = 1;
			else
				if(a[i] == a[i-1])
					arr[i] = arr[i-1]+1;
				else
					arr[i] = 1;
		 }
		ST();
		while(t--)					
		{
			scanf("%d%d",&j,&k);
			temp = j;
			while(temp <= k && a[temp] == a[temp-1])
				temp++;
			ant = Query(temp,k);
			res = max_m(temp-j,ant);
			printf("%d\n",res);
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值