64

对于快排的深刻理解(双关键词)
然后分块 块长 (500000)^(1/3)=80    o((n/k)^2)+n log n+n*k) 理论上最快 实际 4.8s 
更新块间答案(只与下标和数据是否相等有关)
之后查询 块间与暴力相结合
var i,j,k,l,m,n,q,w,x,y:longint;
    a,b,next,c,t:array[0..500000] of longint;
    f:array[0..6300,0..6300] of longint;
function jh(p,o:longint):boolean;
begin
   if a[p]=a[o] then exit(p<o); exit(a[p]<a[o]);
end;
function min(p,o:longint):longint;
begin if p>o then exit(o);exit(p);end;
procedure sort(l,r: longint);
      var i,j,x,y: longint;
      begin
         i:=l; j:=r; x:=b[(l+r)div 2];
         repeat
           while jh(b[i],x) do inc(i);
           while jh(x,b[j]) do dec(j);
           if i<=j then
             begin
                y:=b[i]; b[i]:=b[j]; b[j]:=y;
                inc(i); j:=j-1;
             end;
         until i>=j;
         if l<j then sort(l,j);
         if i<r then sort(i,r);
end;
begin
    readln(n,m); k:=80;l:=n div k+1;
    for i:=1 to n do begin read(a[i]); b[i]:=i; end;
    readln; sort(1,n);
    for i:=1 to n-1 do if a[b[i]]=a[b[i+1]] then next[b[i]]:=b[i+1];
    for i:=1 to n do if (next[i]<>0) then c[i]:=next[i]-i;
    for i:=1 to n do t[i]:=(i-1) div k+1;
    fillchar(f,sizeof(f),$7f);
    for i:=1 to n do if next[i]<>0 then
        f[t[i],t[next[i]]]:=min(c[i],f[t[i],t[next[i]]]);
    for i:=1 to l do for j:=i+1 to l do begin
        f[i,j]:=min(f[i,j-1],f[i,j]); f[i,j]:=min(f[j,j],f[i,j]);end;
    for i:=1 to m  do begin
        readln(x,y);
        x:=x xor q; y:=y xor q;
        if t[y]-t[x]<2 then begin q:=maxlongint;
         for j:=x to y do if (0<next[j])and(next[j]<=y) then q:=min(q,c[j]);
           if q>n then q:=-1;  writeln(q);
        end
        else begin
          q:=f[t[x]+1,t[y]-1];
           for j:=x to t[x]*k do
               if(0<next[j])and(next[j]<=y)then q:=min(q,c[j]);
           for j:=(t[y]-1)*k to y do
                if(0<next[j])and(next[j]<=y)then q:=min(q,c[j]);
           if q>n then q:=-1; writeln(q);
        end;
    end;
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值