joj 2660 河床
rmq的st算法,还有就是从头遍历的小技巧,不然仍然会超时。。。。
#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define MN 40005
int w[30005];
int mi[MN][15],mx[MN][15];
int n,q,k;
void rmqinit()
{
int i,j,m;
for(i=1;i<=n;i++)
{
mi[i][0]=mx[i][0]=w[i];
}
m=floor(log((double)n)/log(2.0));
for(i=1;i<=m;i++)
{
for(j=n;j>=1;j--)
{
mx[j][i]=mx[j][i-1];
if(j+(1<<(i-1))<=n)
mx[j][i]=max(mx[j][i],mx[j+(1<<(i-1))][i-1]);
mi[j][i]=mi[j][i-1];
if(j+(1<<(i-1)<=n))
mi[j][i]=min(mi[j][i],mi[j+(1<<(i-1))][i-1]);
}
}
}
int rmqmin(int l,int r)
{
int m=floor(log((double)(r-l+1))/log(2.0));
return min(mi[l][m],mi[r-(1<<m)+1][m]);
}
int rmqmax(int l,int r)
{
int m=floor(log((double)(r-l+1))/log(2.0));
return max(mx[l][m],mx[r-(1<<m)+1][m]);
}
int main()
{
while(scanf("%d%d",&n,&k),n||k)
{
int i,j;
for(i=1;i<=n;i++)
scanf("%d",&w[i]);
rmqinit();
int mm=1;
int maxx=w[1],minn=w[1],s=1,e=1;
for(i=2;i<=n;i++)
{
int flag=0;
s++;
// cout<<maxx<<" "<<minn<<" "<<w[i]<<endl;
if(w[i]>maxx)
{
maxx=w[i];
if(maxx-minn>k)
{
flag=1;
}
}
else if(w[i]<minn)
{
minn=w[i];
if(maxx-minn>k)
{
flag=1;
}
}
if(flag)
{
e++;
while(e<s&&rmqmax(e,s)-rmqmin(e,s)>k)
e++;
}
maxx=rmqmax(e,s);
minn=rmqmin(e,s);
if(s-e+1>mm)
mm=s-e+1;
//cout<<i<<" "<<s<<" "<<e<<" "<<endl;
}
printf("%d\n",mm);
}
}