树状数组——求和问题题解

题目:求和问题

描述:

【问题描述
    在一个长度为n的整数数列中取出连续的若干个数,并求它们的和。
【输入格式】
    输入由若干行组成,第一行有一个整数n
    第二行有n个整数
    第三行有一个整数m
    下面m行,每行两个整数i与j(i<=j),表示求和的起始和终止位置。
【输出格式】

    输出有m行, 每行一个整数,表示这个数段数列的和。

【输入样例】
输入文件
8
2 3 4 7 8 9 10 234
5
2 3
4 7
1 3
7 7
7 8
 
输出文件
7
34
9
10
244
【数据规模】
对于40%的数据,n<=1000,m<=1000,数列中的数不超过32767,数列的和不超过10^9
对于70%的数据,n<=10000,m<=2*10^5,数列中的数不超过32767
对于100%的数据,n<=10000,m<=2*10^5,数列中的数不超过10^9
 
     果的树状数组,直接处理,查找1~i-1的值和1~j的值,相减即为答案。但数据大小较坑,但int64轻松解决。评论中说有一组数据还有0 0的奇葩情况……于是很多人被坑……感谢评论,直接特判……还有就是,以后一定要注意读入的方式,因为写成了换行读入,结果WA了一次,以后一定要注意。
 
AC代码:
 
{
program zht;
var
n,i,j,t,x,y,m:longint;
q,w:int64;
a,c:array[0..20000] of int64;

begin
assign(input,'sum.in');
assign(output,'sum.out');
reset(input);
rewrite(output);
readln(n);
for i:=1 to n do
read(a[i]);

for i:=1 to n do
begin
t:=i and (-i);
 for j:=i-t+1 to i do
 c[i]:=c[i]+a[j];
end;  // jian shu

t:=0;

readln(m);

for i:=1 to m do
begin
 readln(x,y);
 if x+y=0 then begin writeln('0'); continue; end;
 q:=0;
 w:=0;
 t:=x-1;
  while t>0  do
   begin
   q:=q+c[t];
   t:=t-(t and (-t));
   end;
  t:=y;

  while t>0 do
  begin
  w:=w+c[t];
  t:=t-(t and (-t));
  end;

  writeln(w-q);
end;

close(input);
close(output);

end.
}
<Marvolo原创,严禁转载>

转载于:https://www.cnblogs.com/zhtjtcz/p/4985852.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值