题目:
http://poj.org/problem?id=3368
分析:将原序列转换一下
最后结果为max(前半部分,后半部分)。
分析:将原序列转换一下
if(num[i]==num[i-1])对于每个询问(l,r),分为两个部分,前半部分求与l之前相同的数的个数直到t,后半部分从t开始直接用RMQ求解最大值就行了。
f[i]=f[i-1]+1;
else
f[i]++;
最后结果为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;
}