• PPT1 例5


    题意/Description

      一行N个方格,开始每个格子里的数都是0。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N≤1024,提问和修改的总数可能达到60000条。

     

    读入/Input

      (不详)

      20  //方格个数
      6   //有几组操作
      M 1 1 //表示修改,第一个表示格子位置,第二个数表示在原来的基础上加上的数,
      M 2 2
      M 3 4
      M 3 -5
      M 6 7
      C  2 6  //表示统计 ,第一个数表示起始位置,第二个数表示结束位置

     

    输出/Output

      某一个特定的子区间[a,b]中所有元素的和。(8)

     

    题解/solution

      为线段树每个节点增加一个Count域。表示所对应区间内元素之和。

      每次修改一个格子,需要修改从叶结点到根结点路径上所有结点的值。

      特别注意:题目中的区间是以元素为端点,因此[a,b]和[b,c]存在重合,这和我们之前讨论的区间定义不同。我们这里忽略预处理过程,直接使用之前的区间定义。详情见程序。

     

    代码/Code

    <strong>type
      arr=record
        f:longint;
        count:longint;
      end;
    var
      tree:array [1..41] of arr;
      n,m,k:longint;
    procedure cre(p,l,r:longint);
    var
      m:longint;
    begin
      m:=(l+r) div 2;
      if r-l=1 then
        begin
          inc(k);
          tree[p].f:=k;
          exit;
        end;
      cre(p*2,l,m);
      cre(p*2+1,m,r);
    end;
    
    procedure find(p,l,r,x:longint;var pos:longint);
    var
      m:longint;
    begin
      m:=(l+r) div 2;
      if (r-l=1) then
        begin
          if (tree[p].f=x) then pos:=p;
          exit;
        end;
      find(p*2,l,m,x,pos);
      find(p*2+1,m,r,x,pos)
    end;
    
    procedure modify(p,di:longint);
    begin
      repeat
        tree[p].count:=tree[p].count+di;
        p:=p div 2;
      until p=0;
    end;
    
    function count(p,l,r,a,b:longint):longint;
    var
      m:longint;
    begin
      if (l=a) and (r=b) then count:=tree[p].count else
        begin
          m:=(l+r) div 2;
          if b<=m then count:=count(p*2,l,m,a,b) else
            if a>=m then count:=count(p*2+1,m,r,a,b) else
              count:=count(p*2,l,m,a,m)+count(p*2+1,m,r,m,b);
        end;
    end;
    
    procedure main;
    var
      i,x,y,p:longint;
      ch:char;
    begin
      readln(n); k:=0;
      cre(1,1,10);
      readln(m);
      for i:=1 to m do
        begin
          read(ch);
          case ch of
            'C':begin
                  readln(x,y);
                  writeln(count(1,1,10,x,y+1));
                end;
            'M':begin
                  readln(x,y);
                  find(1,1,10,x,p);
                  modify(p,y);
                end;
          end;
        end;
    end;
    
    begin
      main;
    end.
    </strong>



  • 相关阅读:
    11
    961. N-Repeated Element in Size 2N Array
    用numpy.pad()对图像进行填充及简单的图像处理
    709. To Lower Case
    929. Unique Email Addresses
    771. Jewels and Stones
    谭凯---访谈录
    如何拍照
    主题阅读法
    社会各职业工作重心和流程
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9319700.html
Copyright © 2020-2023  润新知