zoukankan      html  css  js  c++  java
  • A Simple Problem with Integers(线段树区间更新模板题)

    A Simple Problem with Integers
    Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u
    Submit Status

    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.
     
      1 //Memory: 4324 KB        Time: 1594 MS
      2 //Language: C++        Result: Accepted
      3 
      4 #include <iostream>
      5 #include <cstdio>
      6 
      7 using namespace std;
      8 
      9 typedef long long ll;
     10 #define ls rt<<1
     11 #define rs rt<<1|1
     12 
     13 const int sz = 100001;
     14 struct Tree
     15 {
     16      ll sum, inc;
     17 }t[sz<<2];
     18 ll d, ans;
     19 
     20 void build(const int left, const int right, const int rt)
     21 {
     22     t[rt].inc = 0;
     23     if(right == left)
     24     {
     25         scanf("%I64d", &t[rt].sum);
     26         return ;
     27     }
     28     int mid = (right + left) >> 1;
     29     build(left, mid, ls);
     30     build(mid + 1, right, rs);
     31     t[rt].sum = t[ls].sum + t[rs].sum;
     32     return ;
     33 }
     34 
     35 void update(const int l, const int r, const int from, const int to, const int rt)
     36 {
     37     if(from <= l && r <= to)
     38     {
     39         t[rt].inc += d;
     40         t[rt].sum += ((ll)(r - l + 1) * d);  //(1)
     41         return ;
     42     }
     43     if(t[rt].inc)
     44     {
     45         t[ls].inc += t[rt].inc;
     46         t[rs].inc += t[rt].inc;
     47         t[ls].sum += ((ll)((r - l + 2) >> 1) * t[rt].inc);  //(2)
     48         t[rs].sum += ((ll)((r - l + 1) >> 1) * t[rt].inc);
     49         t[rt].inc = 0;
     50     }
     51     int mid = (l + r) >> 1;
     52     if(from <= mid) update(l, mid, from, to, ls);
     53     if(to > mid) update(mid + 1, r, from, to, rs);
     54     t[rt].sum = t[ls].sum + t[rs].sum;
     55     return ;
     56 }
     57 
     58 void query(const int l, const int r, const int from, const int to, const int rt)
     59 {
     60     if(from <= l && r <= to)
     61     {
     62         ans += t[rt].sum;
     63         return ;
     64     }
     65     if(t[rt].inc)
     66     {
     67         t[ls].inc += t[rt].inc;
     68         t[rs].inc += t[rt].inc;
     69         t[ls].sum += ((ll)((r - l + 2) >> 1) * t[rt].inc);
     70         t[rs].sum += ((ll)((r - l + 1) >> 1) * t[rt].inc);
     71         t[rt].inc = 0;
     72     }
     73     int mid = (l + r) >> 1;
     74     if(from <= mid) query(l, mid, from, to, ls);
     75     if(to > mid) query(mid + 1, r, from, to, rs);
     76     return ;
     77 }
     78 
     79 int main()
     80 {
     81     int q, n, a, b;
     82     char cmd;
     83     while(scanf("%d %d", &n, &q) != EOF)
     84     {
     85         build(1, n, 1);
     86         while(q--)
     87         {
     88             cin >> cmd;
     89             if(cmd == 'Q')
     90             {
     91                 scanf("%d %d", &a, &b);
     92                 ans = 0;
     93                 query(1, n, a, b, 1);
     94                 printf("%I64d\n", ans);
     95             }
     96             else
     97             {
     98                 scanf("%d %d %I64d", &a, &b, &d);
     99                 update(1, n, a, b, 1);
    100             }
    101         }
    102     }
    103     return 0;
    104 }
    105 /*
    106 (1) *d而非*t[rt].inc,因为t[rt].inc是保存rt的儿子的更新数据的,到达rt的更新是d
    107 (2) *t[rt].inc而非*t[ls].inc,因为t[ls].inc是保存ls的儿子的更新数据的。到达ls的更新是
    108 t[rt].inc.(r - l + 2) >> 1是ls的左儿子的区间长度,(r - l + 1) >> 1是右儿子的区间长度。
    109 实际上(r - l + 2) >> 1是(r - l + 1) / 2.0的向上取整。注意由于在build中,mid归于左儿子,
    110 故左儿子的区间长度>=右儿子区间长度
    111 */
  • 相关阅读:
    python 包管理工具 pip 的配置
    Python 变量作用域 LEGB (下)—— Enclosing function locals
    Python 变量作用域 LEGB (上)—— Local,Global,Builtin
    2020 Java 面试题 小结 (答案慢慢补上,有错误请指出)
    mysql 根据日期(date)做年,月,日分组统计查询
    jvm指令
    正则表达式 分割地址 获取省市区详细地址
    .Net 异常记录
    WCF设计服务协议(一)
    plsql ORA-01789:查询块具有不正确的结果列数
  • 原文地址:https://www.cnblogs.com/cszlg/p/3072419.html
Copyright © 2011-2022 走看看