zoukankan      html  css  js  c++  java
  • POJ 3468 A Simple Problem with Integers(线段树)

    A Simple Problem with Integers
    Time Limit: 5000MS   Memory Limit: 131072K
    Total Submissions: 126311   Accepted: 39238
    Case Time Limit: 2000MS

    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

     1 #include <iostream>
     2 #include <cstring>
     3 #include <string>
     4 #include <algorithm>
     5 typedef long long ll;
     6 using namespace std;
     7 int n, q;
     8 struct node
     9 {
    10     int l, r;
    11     ll date;//区间内每个数都要加的数
    12     ll datb;//数据的和
    13 }a[400005];
    14 
    15 
    16 void build(int l,int r,int k)
    17 {
    18     a[k].l = l; a[k].r = r;
    19     if (r == l)
    20     {
    21         scanf("%lld", &a[k].datb);
    22         return;
    23     }
    24     int mid = (l + r) / 2;//传的是l和r,不是a[k].l和a[k].r
    25     build(l, mid , 2 * k);
    26     build(mid + 1, r, 2 * k + 1);
    27     a[k].datb = a[2 * k].datb + a[2 * k + 1].datb;
    28 }
    29 
    30 void add(int k,int l,int r,int v)
    31 {
    32     if (a[k].l >= l && r >= a[k].r)//如果区间刚好在a[k].l和a[k].r之间
    33         a[k].date += v;//每个数都要加,所以放到date中
    34     else if(a[k].l<=r&&l<=a[k].r)//部分重叠的话
    35     {
    36         a[k].datb+= (min(r, a[k].r) - max(l, a[k].l)+1)*v;//我加号居然忘了
    37         add(2 * k, l,r, v);
    38         add(2 * k + 1,l, r, v);
    39     }
    40     //否则跳出循环
    41 }
    42 
    43 ll Sum(int l, int r,int k)
    44 {
    45     if (l > a[k].r||r < a[k].l)
    46         return 0;
    47     else if (l <= a[k].l&&r >= a[k].r)
    48     {
    49         /*cout << "a[k].l " << a[k].l << " a[k].r " << a[k].r << endl;
    50         cout << a[k].datb + a[k].date *(a[k].r - a[k].l + 1) << endl;*/
    51         return a[k].datb + a[k].date *(a[k].r - a[k].l + 1);
    52     }
    53     else
    54     {
    55         ll ans = (min(a[k].r, r) - max(a[k].l, l)+1)*a[k].date;
    56         ans += Sum(l, r, k * 2);//传的是l和r,不是a[k].l和a[k].r
    57         ans += Sum(l, r, k * 2 + 1);
    58         return ans;
    59     }
    60 }
    61 
    62 int main()
    63 {
    64     while (~scanf("%d%d", &n, &q))
    65     {
    66         for (int i = 0; i <= 400000; i++)
    67             a[i].datb = a[i].date = 0;
    68         build(1, n, 1);
    69         while (q--)
    70         {
    71             char s;
    72             int x, y;
    73             cin >> s >> x >> y;
    74             if (s == 'C')
    75             {
    76                 int z;
    77                 cin >> z;
    78                 add(1, x, y, z);
    79             }
    80             else
    81             {
    82                 ll sum = Sum(x, y, 1);
    83                 printf("%lld
    ", sum);
    84             }
    85         }
    86     }
    87     return 0;
    88 }
     
  • 相关阅读:
    图片切换的练习
    固定定位
    绝对定位
    相对定位
    全局作用域 变量声明
    3种循环语句 JS基础
    解除绑定事件 和 封装兼容性addEvent 来处理针对于不同浏览器的兼容方法
    插入排序法 猴子选大王 检索的数组 验证身份证号码 练习
    [z]JSONP例子
    ireport related
  • 原文地址:https://www.cnblogs.com/caiyishuai/p/13271154.html
Copyright © 2011-2022 走看看