区间问题:两道线段树和树状数组的基础练习

万能的线段树和非常简单但是和好用的树状数组,早有耳闻,但一直找不到题目练习,只是照着书上的程序打了一遍练练手而已。最近发现POJ和HDU的acm题库资源真的很丰富呃,先练练手复习一下吧

POJ 2352  求点左下区域的点数,因为数据已经按从下往上,从左到右排序,所以可以用统计当前1到x的点数和就是答案,树状数组即可解决。但是因为树状数组不能处理0下标,代码有点小改动

const

  maxn=100000;

var

  c,level:array[0..1000000] of longint;

  i,j,k,n,m,x,y:longint;

function lowbit(i:longint):longint;

begin

  exit(i and -i);

end;



procedure add(i,x:longint);

begin

  while i<=maxn do

  begin

    c[i]:=c[i]+x;

    i:=i+lowbit(i);

  end;

end;



function getsum(i:longint):longint;

begin

  getsum:=0;

  while i>0 do

  begin

    getsum:=getsum+c[i];

    i:=i-lowbit(i);

  end;

end;







begin

  readln(n);

  for i:=1 to n do

  begin

    readln(x,y);

    add(x+1,1);

    inc(level[getsum(x+1)-1]);

  end;

  for i:=0 to n-1 do

    writeln(level[i]);

end.

HDU 1754 没穿衣服的区间最值问题,线段树基础练习

我的代码仅能通过样例,提交显示编译失败,难道Delphi语法差那么多吗?我在FP下用Delphi模式也能编译通过啊……

type

  node=record l,r,c:longint; end;

var

  tree:array[1..20000] of node;

  a:array[1..20000] of longint;

  n,m,i,x,y:longint;

  maxnum:longint;

  c,c1:char;

function max(a,b:longint):longint;

begin

  if a>b then exit(a) else exit(b);

end;

procedure build(p,l,r:longint);

begin

  tree[p].l:=l;

  tree[p].r:=r;

  if l=r then

    tree[p].c:=a[l]

  else begin

    build(p*2,l,(l+r) div 2);

    build(p*2+1,(l+r) div 2+1,r);

    tree[p].c:=max(tree[p*2].c,tree[p*2+1].c);

  end;

end;

procedure find(p,l,r:longint);

var

  m:longint;

begin

   if (l<=tree[p].l)and(tree[p].r<=r) then

     maxnum:=max(maxnum,tree[p].c)

   else begin

     m:=(tree[p].l+tree[p].r) div 2;

     if r<=m then

       find(p*2,l,r)

     else if l>m then

       find(p*2+1,l,r)

     else begin

       find(p*2,l,m);

       find(p*2+1,m+1,r);

     end;

   end;

end;



procedure insert(p:longint);

var

  m:longint;

begin

  if tree[p].l=tree[p].r then

    tree[p].c:=y

  else begin

    m:=(tree[p].l+tree[p].r) div 2;

    if m>=x then

      insert(p*2)

    else insert(p*2+1);

    tree[p].c:=max(tree[p*2].c,tree[p*2+1].c);

  end;

end;



begin

  while not eof do

  begin

    readln(n,m);

    for i:=1 to n do

      read(a[i]);

    readln;

    build(1,1,n);

    for i:=1 to m do

    begin

      readln(c,x,y);

      if c='Q' then

      begin

        maxnum:=-1;

        find(1,x,y);

        writeln(maxnum);

      end

      else if c='U' then

        insert(1);

    end;

  end;

end.

你可能感兴趣的:(树状数组)