bzoj1293: [SCOI2009]生日礼物

传送门
枚举起点找出每一种颜色在这个位置之后的第一个位置与这个位置距离的最大值,再找出每一个起点结果的最小值
转移时将当前节点坐标转移到下一个有这个颜色的位置。
可以用堆或者这个是叫做单调队列么?

uses math;
var
  a:array [0..1000006] of longint;
  p,h,l:array [0..65] of longint;
  n,m,i,j,k,ma,mi,ans:longint;
procedure kp(l,r:longint);
  var i,j,m,t:longint;
  begin
    i:=l; j:=r; m:=a[(l+r) div 2];
    while (i<=j) do begin
      while (a[i]<m) and (i<=r) do inc(i);
      while (a[j]>m) and (j>=l) do dec(j);
      if (i<=j) then begin
        t:=a[i]; a[i]:=a[j]; a[j]:=t;
        inc(i); dec(j);
    end; end;
    if (l<j) then kp(l,j);
    if (i<r) then kp(i,r);
  end;
begin
  read(n,m);
  for i:=1 to m do begin
    read(l[i]); h[i]:=h[i-1]+l[i-1];
    for j:=h[i] to h[i]+l[i]-1 do read(a[j]);
  end;
  p:=h; p[m+1]:=n+1;
  ma:=0; mi:=maxlongint;
  for i:=1 to m do begin
    if (a[h[i]]>ma) then ma:=a[h[i]];
    if (a[h[i]]<mi) then mi:=a[h[i]];
  end;
  ans:=ma-mi;
  for i:=1 to n-m do
    begin
      k:=0;
      for j:=1 to m do
        if (h[j]+1<>p[j+1]) then
          if (k=0) or (a[h[j]]<a[h[k]]) or ((a[h[j]]=a[h[k]]) and (a[h[j]+1]<a[h[k]+1])) then k:=j;
      inc(h[k]);
      ma:=0; mi:=maxlongint;
      for j:=1 to m do begin
        if (a[h[j]]>ma) then ma:=a[h[j]];
        if (a[h[j]]<mi) then mi:=a[h[j]];
      end;
      ans:=min(ans,ma-mi);
    end;
  write(ans);
end.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值