poj3468 A Simple Problem with Integers(线段树/树状数组)

Description

You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

Sample Output

4
55
9
15

Hint

The sums may exceed the range of 32-bit integers.

Source

POJ Monthly--2007.11.25, Yang Yi
 
题目大意:

上图最后一行打错了,应该似乎求a[l]到a[r]的和。

线段树做法太裸,直接贴代码:

 1 program rrr(input,output);
 2 type
 3   treetype=record
 4      l,r:longint;
 5      sum,d:int64;
 6   end;
 7 var
 8   a:array[0..400040]of treetype;
 9   c:array[0..100010]of longint;
10   n,q,i,x,y,d:longint;
11   ch:char;
12 procedure build(k,l,r:longint);
13 var
14   mid,i:longint;
15 begin
16    a[k].l:=l;a[k].r:=r;a[k].d:=0;
17    if l=r then begin a[k].sum:=c[l];exit; end;
18    mid:=(l+r)>>1;i:=k+k;
19    build(i,l,mid);build(i+1,mid+1,r);
20    a[k].sum:=a[i].sum+a[i+1].sum;
21 end;
22 procedure pushdown(k:longint);
23 var
24   i:longint;
25 begin
26    if a[k].l=a[k].r then a[k].d:=0;
27    if a[k].d=0 then exit;
28    i:=k+k;a[i].sum:=a[i].sum+(a[i].r-a[i].l+1)*a[k].d;a[i].d:=a[i].d+a[k].d;
29    inc(i);a[i].sum:=a[i].sum+(a[i].r-a[i].l+1)*a[k].d;a[i].d:=a[i].d+a[k].d;
30    a[k].d:=0;
31 end;
32 function ask(k:longint):int64;
33 var
34   mid:longint;
35   ans:int64;
36 begin
37    pushdown(k);
38    if (x<=a[k].l) and (a[k].r<=y) then exit(a[k].sum);
39    mid:=(a[k].l+a[k].r)>>1;ans:=0;
40    if x<=mid then ans:=ask(k+k);
41    if mid<y then ans:=ans+ask(k+k+1);
42    exit(ans);
43 end;
44 procedure change(k:longint);
45 var
46   mid,i:longint;
47 begin
48    pushdown(k);
49    if (x<=a[k].l) and (a[k].r<=y) then begin a[k].sum:=a[k].sum+d*(a[k].r-a[k].l+1);a[k].d:=d;exit; end;
50    mid:=(a[k].l+a[k].r)>>1;i:=k+k;
51    if x<=mid then change(i);
52    if mid<y then change(i+1);
53    a[k].sum:=a[i].sum+a[i+1].sum;
54 end;
55 begin
56    assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
57    readln(n,q);
58    for i:=1 to n do read(c[i]);readln;
59    build(1,1,n);
60    for i:=1 to q do
61       begin
62          read(ch,x,y);
63          if ch='Q' then writeln(ask(1))
64          else begin read(d);change(1); end;
65          readln;
66       end;
67    close(input);close(output);
68 end.

下面是树状数组做法:

代码(实测比线段树快1倍):

 1 program rrr(input,output);
 2 var
 3   a,b:array[0..100010]of int64;
 4   n,q,i:longint;
 5   c:char;
 6   ans,x,y,z:int64;
 7 procedure adda(k,x:int64);
 8 begin
 9    while k<=n do begin a[k]:=a[k]+x;k:=k+k and (-k); end;
10 end;
11 procedure addb(k,x:int64);
12 begin
13    while k<=n do begin b[k]:=b[k]+x;k:=k+k and (-k); end;
14 end;
15 function suma(k:longint):int64;
16 begin
17    ans:=0;
18    while k>0 do begin ans:=ans+a[k];k:=k-k and (-k); end;
19    exit(ans);
20 end;
21 function sumb(k:longint):int64;
22 begin
23    ans:=0;
24    while k>0 do begin ans:=ans+b[k];k:=k-k and (-k); end;
25    exit(ans);
26 end;
27 begin
28    assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
29    readln(n,q);
30    fillchar(a,sizeof(a),0);
31    fillchar(b,sizeof(b),0);
32    for i:=1 to n do begin read(z);adda(i,z); end;readln;
33    for i:=1 to q do
34       begin
35          read(c,x,y);
36          if c='Q' then writeln(suma(y)+sumb(y)*y-suma(x-1)-sumb(x-1)*(x-1))
37          else begin read(z);adda(x,-z*(x-1));addb(x,z);adda(y,z*y);addb(y,-z); end;
38          readln;
39       end;
40    close(input);close(output);
41 end.

 

posted @ 2017-04-09 20:07  Klaier  阅读(194)  评论(0编辑  收藏  举报