解题报告 Loongint 的花篮
1. 题目
Loongint的花篮
【Description】
Loongint要和MM结婚了。在两人的走进礼堂的红地毯两侧,需要摆一些装饰用的花篮,有一些不同高度的花篮,现在这些花篮被Loongint依照自己的美学观念编号为S1,S2,S3…Sn(两侧的花篮高度一样)。可Loongint的MM对这些花篮的摆放方式有不同的看法,她觉得满足以下条件的花篮摆放才是最好的。
如果对于区间[Si,Sj](1<=i<j<=n)中任意的花篮都比Si高且比Sj低,那么这个区间称为一个美学区间。对于所有的美学区间,其长度(定义为j-i)都必须小于等于k,如果有长度大于k的美学区间,MM就会不高兴,Loongint就会有麻烦…
【Input】
第一行为m。表示有m组测试数据。
对于每一组:
第一行n,k,分别表示花篮的数量和美学区间的最大长度。
第二行为n个数,分别表示S1,S2,S3…Sn的值。
【Output】
如果根本不存在美学区间,输出-1。
如果存在美学区间,那么如果任意区间的长度都小于等于k,那么输出最大的长度,否则输出最大长度比k大多少(MaxLength-k)。
【Sample Input】
3
4 2
5 4 3 6
4 1
6 5 4 3
4 2
1 2 3 4
【Sample Output】
1
-1
1
【Hint】
对于30%的测试数据,1<=n<=100。
对于60%的测试数据,1=<n<=5555。
对于100%的测试数据,1<=n<=100000,0<Si<=100000,1=<m<=3。
2. 算法
枚举一个点,从这个点开始,维护两个单调栈,向前后两个方向分别扩展,然后枚举右端点,再从这个端点向左扩展,当能够扩展过枚举的这个构件这两个单调栈的点时,记录一下长度,并更新。
3. 注意事项
单调栈的操作,枚举端点。
4. 代码
var
m,n,k,i,j,ii,top,ans:longint;
a:array[0..100001] of longint;
stack,l,r:array[0..100001] of longint;
begin
assign(input,'baskets.in');
assign(output,'baskets.out');
reset(input);
rewrite(output);
readln(m);
for ii:=1 to m do
begin
readln(n,k);
for i:=1 to n do
read(a[i]);
top:=1;
stack[1]:=1;
a[n+1]:=-maxlongint;
for i:=1 to n do
begin
r[i]:=i;
l[i]:=i;
end;
for i:=2 to n+1 do
begin
if a[i]>a[stack[top]]then
begin
inc(top);
stack[top]:=i;
end
else
if a[i]<=a[stack[top]] then
begin
while (a[i]<=a[stack[top]]) and(top>0) do
begin
r[stack[top]]:=i-1;
dec(top);
end;
inc(top);
stack[top]:=i;
end;
end;
a[0]:=maxlongint;
top:=1;
stack[1]:=n;
for i:=n-1 downto 0 do
begin
if a[i]<a[stack[top]]t