AcWing 243. 一个简单的整数问题2-(区间修改,区间查询)

发布时间 2023-03-31 16:35:16作者: 回忆、少年

给定一个长度为 N 的数列 A,以及 M 条指令,每条指令可能是以下两种之一:

  1. C l r d,表示把 A[l],A[l+1],,A[r]都加上 d
  2. Q l r,表示询问数列中第 lr个数的和。

对于每个询问,输出一个整数表示答案。

输入格式

第一行两个整数 N,M

第二行 N 个整数 A[i]

接下来 M行表示 M 条指令,每条指令的格式如题目描述所示。

输出格式

对于每个询问,输出一个整数表示答案。

每个答案占一行。

数据范围

1N,M1e5,
|d|10000,
|A[i]|1e9

输入样例:

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

输出样例:

4
55
9
15

代码实现:

#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int N=1e5+5;
int a[N],tr1[N],tr2[N];
int n,m;
int lowbit(int x){
    return x&-x;
}
void add(int tr[],int x,int y){
    for(int i=x;i<=n;i+=lowbit(i))tr[i]+=y;
}
int query(int tr[],int x){
    int res=0;
    for(int i=x;i;i-=lowbit(i))res+=tr[i];
    return res;
}
int pre(int x){
    return (x+1)*query(tr1,x)-query(tr2,x);
}
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        int x=a[i]-a[i-1];
        add(tr1,i,x);
        add(tr2,i,i*x);
    }
    while(m--){
        string s;
        cin>>s;
        int x,y,z;
        if(s[0]=='C'){
            cin>>x>>y>>z;
            add(tr1,x,z),add(tr2,x,x*z);
            add(tr1,y+1,-z),add(tr2,y+1,(y+1)*-z);
        }else{
            cin>>x>>y;
            cout<<pre(y)-pre(x-1)<<endl;
        }
    }
    return 0;
}