Description
地理学家们经常要对一段河流进行测量分析。他们从上游开始向下游方向等距离地选择n(<=30000)个点测量水位深度。得到一组数据d1,d2,…,dn,回到实验室后数据分析员根据需要对数据进行分析,发掘隐藏在数据背后的规律。最近,乌龙博士发现某种水文现象与河床地势有关,于是他指示他手下的分析员要找出一段河流中最大高低起伏差不超过k(k<=100)的最长一段。这看似一个复杂的问题,由于任务紧急,分析员来求助于你,并告诉你博士的所有数据都精确到个位。
Input
输入文件有两行:第一行是整数n,k,分别表示测量点的个数和博士要求的最大水深差(也就是河床地势差)。第二行有n个整数,表示从上游开始依次得到的水位深度 di(1<=i<=n,0<=di<=32767)。
Output
输出文件只有一行,是整数m,表示最长一段起伏不超过k的河流长度,用测量点个数表示。
Sample Input
6 2
5 3 2 2 4 5
Sample Output
4
Data Constraint
Hint
提示:从第二个测量点到第五个测量点之间的那段:3 2 2 4,他们起伏最大时4-2=2。
题解
一眼DP的题,而且还是单调队列。
但是姿势水平不够,DP解法留坑。
ST表维护最大值和最小值,然后二分答案,O(n)判断,总复杂度O(nlogn)
据说有暴力+去重+break可以跑得比我快qwq
var n,k,i,j,l,r,mid,ans:longint;
lg,a:array[0..100000]of longint;
f1,f2,f3:array[0..100000,0..20]of longint;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
function min(x,y:longint):longint;
begin
if x>y then exit(y) else exit(x);
end;
begin
readln(n,k);
for i:=1 to n do read(a[i]);
readln;
for i:=1 to n-1 do begin
f1[i,0]:=i+1;
f2[i,0]:=max(a[i+1],a[i]);
f3[i,0]:=min(a[i+1],a[i]);
end;
for i:=1 to 18 do begin
for j:=1 to n do begin
f1[j,i]:=f1[f1[j,i-1],i-1];
f2[j,i]:=max(f2[j,i-1],f2[f1[j,i-1],i-1]);
f3[j,i]:=min(f3[j,i-1],f3[f1[j,i-1],i-1]);
end;
end;
for i:=2 to n do lg[i]:=lg[i div 2]+1;
l:=1;
r:=n;
while l<=r do begin
mid:=(l+r)div 2;
for i:=1 to n-mid do begin
if max(f2[i,lg[mid]],f2[i+mid-(1 shl lg[mid]),lg[mid]])-min(f3[i,lg[mid]],f3[i+mid-(1 shl lg[mid]),lg[mid]])<=k then begin
ans:=mid+1;
break;
end;
end;
if ans=mid+1 then l:=mid+1 else r:=mid-1;
end;
if ans=0 then ans:=1;
writeln(ans);
end.