您的位置:首页 > 其它

poj3468 A Simple Problem with Integers 2011-12-20

2016-03-02 17:36 204 查看
A Simple Problem with Integers

Time Limit: 5000MSMemory Limit: 131072K

Total Submissions: 26062Accepted: 7202

Case Time Limit: 2000MS

Description

You have N integers, A1, A2, ... , 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 A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.

Each of the next Q lines represents an operation.

"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.

"Q a b" means querying the sum of Aa, Aa+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

_________________________________________________

给一串数,两种操作:一是将一段区间的每个数都加上一个数。二是询问一段区间的和。

_________________________________________________

线段树,没有其他多余的操作,也是以前学非递归的线段树时做的。

_________________________________________________

program Stone;

const T2=1 shl 17-1;

var i,j:longint;

n,q,x,y,z:int64;

ans:int64;

a,sx:array[1..2*T2+2]of int64;

b,sum:array[0..100000]of int64;

procedure add(x,y,z:int64);                  //修改

var s,i:int64;

begin

x:=x+T2-1;y:=y+T2+1;s:=1;

while (x xor y)<>1 do                     //非递归的线段树,主要采取二进制的思想吧。

begin

if (x and 1)=0 then begin

inc(a[x+1],z);i:=x+1;

repeat

sx[i]:=sx[i]+z*s;i:=i div 2;

until i=1;

end;

if (y and 1)=1 then begin

inc(a[y-1],z);i:=y-1;

repeat

sx[i]:=sx[i]+z*s;i:=i div 2;

until i=1;

end;

x:=x div 2;y:=y div 2;s:=s*2;

end;

end;

procedure que(x,y:int64);                    //询问

var r,l,s:int64;

begin

ans:=sum[y-1]-sum[x-2];

x:=x+T2-1;y:=y+T2+1;

r:=0;l:=0;s:=1;

while (x xor y)<>1 do

begin

if (x and 1)=0 then begin l:=l+s;ans:=ans+sx[x+1];end;

if (y and 1)=1 then begin r:=r+s;ans:=ans+sx[y-1];end;

x:=x div 2;y:=y div 2;s:=s*2;

ans:=ans+l*a[x]+r*a[y];

end;

while y<>1 do

begin

y:=y div 2;ans:=ans+a[y]*(l+r);s:=s*2;

end;

writeln(ans);

end;

procedure init;

var c,sp:char;

begin

readln(n,q);

for i:=1 to n do

begin

read(b[i]);sum[i]:=sum[i-1]+b[i];         //初始化

end;

readln;

for i:=1 to q do

begin

read(c,sp,x,y);

inc(x);inc(y);

if c='C' then begin read(z);add(x,y,z);end;

if c='Q' then que(x,y);

readln;

end;

end;

begin

assign(input,'pku3468.in');assign(output,'pku3468.out');

reset(input);rewrite(output);

init;

close(input);close(output);

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: