PPT1 例5

来源:互联网 发布:linux编程获取串口参数 编辑:程序博客网 时间:2024/05/20 09:07

题意/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>


2 0
原创粉丝点击