• 3468 A Simple Problem with Integers


    资源限制

    Time Limit: 5000MS  Memory Limit: 131072K  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.
     
     
    这是一道树状数组-[区间更新 区间查询]模板题,详情点击这里.

    以下,A[i]代表原数组,D[j]代表差分数组.

     ∑ni = 1A[i] = ∑ni = 1ij = 1D[j];

     则 A[1]+A[2]+...+A[n]

       = (D[1]) + (D[1]+D[2]) + ... + (D[1]+D[2]+...+D[n]) 

       = n*D[1] + (n-1)*D[2] +... +D[n]

       = n * (D[1]+D[2]+...+D[n]) - (0*D[1]+1*D[2]+...+(n-1)*D[n])

    所以上式可以变为∑ni = 1A[i] = n*∑ni = 1D[i] - ∑ni = 1( D[i]*(i-1) );

    于是,维护两个树状数组,sum1[i] = D[i],sum2[i] = D[i]*(i-1);

    ※注意:题目中也有提醒道,本题数据较大,要用long long.

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <string>
     6 #include <cmath>
     7 #include <algorithm>
     8 #define INF 0x3f3f3f3f
     9 #define zero 1e-7
    10 
    11 using namespace std;
    12 typedef long long ll;
    13 const ll mod=1000000007;
    14 const ll max_n=100005;
    15 ll a[max_n]={0};
    16 ll sum1[max_n]={0}, sum2[max_n]={0};
    17 ll n;
    18 
    19 ll lowbit(ll x) {
    20     return x&(-x);
    21 }
    22 
    23 void update(ll i, ll k) {
    24     ll temp=i;
    25     while(i<=n) {
    26         sum1[i]+=k;
    27         sum2[i]+=(temp-1)*k;
    28         i+=lowbit(i);
    29     }
    30 }
    31 
    32 ll getsum(ll i) {
    33     ll res=0;
    34     ll temp=i;
    35     while(i>0) {
    36         res+=temp*sum1[i]-sum2[i];
    37         i-=lowbit(i);
    38     }
    39     return res;
    40 }
    41 
    42 int main() {
    43     ll q;
    44     cin>>n>>q;
    45     for(ll i=1; i<=n; i++) {
    46         scanf("%I64d", &a[i]);
    47         update(i, a[i]-a[i-1]);
    48     }
    49     char opt;
    50     ll a, b, c;
    51     for(ll i=0; i<q; i++) {
    52         scanf(" %c", &opt);
    53         if(opt=='C') {
    54             scanf("%I64d %I64d %I64d", &a, &b, &c);
    55             update(a, c);
    56             update(b+1, -c);
    57         }
    58         else {
    59             scanf("%I64d %I64d", &a, &b);
    60             printf("%I64d
    ", getsum(b)-getsum(a-1));
    61         }
    62     }
    63     return 0;
    64 }
  • 相关阅读:
    22(1).模型融合---Random Forest
    Tesseract 模块
    非线性问题的三种处理方法
    jupyter 快捷键
    回归评价指标---MSE、RMSE、MAE、R-Squared
    理解JavaScript中的事件处理
    jquery事件重复绑定解决办法
    IE6 IE7 IE8(Q) 不支持 JSON 对象
    浏览器事件机制与自定义事件的实现
    浏览器加载和渲染html的顺序
  • 原文地址:https://www.cnblogs.com/wwqzbl/p/13529450.html
Copyright © 2020-2023  润新知