zoukankan      html  css  js  c++  java
  • 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.
  • 相关阅读:
    lLinux 下 Stress 压力测试工具
    zabbix 微信告警配置
    spark Intellij IDEA开发环境搭建
    Spark调优与调试
    在centos 6.5 x64中安装 spark-1.5.1
    二叉树的各种遍历算法
    ServletResponse的一些知识点
    UVA 10303 How Many Trees? (catlan)
    UVA 10183 How Many Fibs?
    UVA 10471 Gift Exchanging
  • 原文地址:https://www.cnblogs.com/Currier/p/6686138.html
Copyright © 2011-2022 走看看