首页 > 代码库 > HNOI2010弹飞绵羊(块状数组)

HNOI2010弹飞绵羊(块状数组)

不得不说块状数组好神奇的啊!这道题的标签可是splay的启发是合并(什么高大上的东西),竟然这么轻松的就解决了!

var x,y,i,j,tot,n,m,ch:longint;
    f,k,l,bl,go:array[0..200100] of longint;
procedure init;
 begin
 readln(n);
 x:=trunc(sqrt(n));j:=x;
 for i:=1 to n do
  begin
  if j=x then begin j:=1;inc(tot);l[tot]:=i;end
  else inc(j);
  read(k[i]);
  bl[i]:=tot;
  end;
 l[tot+1]:=n+1;
 for i:=n downto 1 do
  if i+k[i]>=l[bl[i]+1] then begin f[i]:=1;go[i]:=i+k[i];end
  else begin f[i]:=f[i+k[i]]+1;go[i]:=go[i+k[i]];end;
 end;
function ask(x:longint):longint;
 var sum:longint;
 begin
 sum:=0;
 while x<=n do begin inc(sum,f[x]);x:=go[x];end;
 exit(sum);
 end;
procedure replace(x,y:longint);
 var  i:longint;
 begin
 k[x]:=y;
 for i:=x downto l[bl[x]] do
  if i+k[i]>=l[bl[i]+1] then begin f[i]:=1;go[i]:=i+k[i];end
  else begin f[i]:=f[i+k[i]]+1;go[i]:=go[i+k[i]];end;
 end;
procedure main;
 begin
 readln(m);
 for i:=1 to m do
  begin
  read(ch);
  if ch=1 then
   begin
   readln(x);inc(x);
   writeln(ask(x));
   end
  else
   begin
   readln(x,y);inc(x);
   replace(x,y);
   end;
  end;
 end;
begin
 init;
 main;
end.