首页 > 代码库 > [bzoj3211]花神游历各国

[bzoj3211]花神游历各国

Description

 技术分享

Input

 技术分享

 

Output

每次x=1时,每行一个整数,表示这次旅行的开心度

Sample Input

4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4

Sample Output

101
11
11

HINT

对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9

Source

SPOJ2713 gss4 数据已加强

Solution

显然是一道线段树,开根号直接暴力就可以了,对于任意一个数最多开5次就变为1,之后就不要在开根了,打一个Tag记录一下。

type
  tree=record
    s,q,l,r:int64;
  end;
var
  n,m,k,x,y,i:longint;
  f:array [0..200000] of tree;
  a:array [0..200000] of longint;
procedure build(x,l,r:longint);
begin
  f[x].l:=l;f[x].r:=r;
  if l=r then
    begin
      f[x].s:=a[l];
      if (f[x].s=1) or (f[x].s=0)
        then f[x].q:=1
        else f[x].q:=0;
      exit;
    end;
  build(x<<1,l,(l+r) >> 1);
  build(x<<1+1,(l+r) >> 1+1,r);
  f[x].s:=f[x<<1].s+f[x<<1+1].s;
  f[x].q:=f[x<<1].q and f[x<<1+1].q;
end;

function plus(x,l,r:longint):int64;
var
  mid:longint;
begin
  plus:=0;
  if (f[x].l=l) and (f[x].r=r) then exit(f[x].s);
  mid:=(f[x].l+f[x].r)>>1;
  if mid>=r
    then plus:=plus+plus(x<<1,l,r);
  if mid<l
    then plus:=plus+plus(x<<1+1,l,r);
  if (mid>=l) and (mid<r)
    then begin plus:=plus(x<<1,l,r)+plus(x<<1+1,l,r) end;
end;

procedure sq(x,l,r:longint);
var
  mid:longint;
begin
  if f[x].q=1
    then exit;
  if (f[x].l=f[x].r) then
    begin
      f[x].s:=trunc(sqrt(f[x].s));
      if (f[x].s=1) or (f[x].s=0)
        then f[x].q:=1;
      exit;
    end;
  mid:=(f[x].l+f[x].r)>>1;
  if mid>=r
    then sq(x<<1,l,r);
  if mid<l
    then sq(x<<1+1,l,r);
  if (mid>=l) and (mid<r)
    then begin sq(x<<1,l,r);sq(x<<1+1,l,r) end;
  f[x].q:=f[x<<1].q and f[x<<1+1].q;
  f[x].s:=f[x<<1].s+f[x<<1+1].s;
end;

begin
  read(n);
  for i:=1 to n do
    begin
      read(a[i]);
    end;
  build(1,1,n);
  read(m);
  for i:=1 to m do
    begin
      read(k,x,y);
      case k of
        1:writeln(plus(1,x,y));
        2:sq(1,x,y);
      end;
    end;
end.

 

 

[bzoj3211]花神游历各国