【差分区间操作 单点查询】 A simple problem with Integer

传送门

题意

给定一个长度为\(N\)的序列\(A\),然后输入\(M\)个指令,指令包含以下两种

  • 第一类指令形如\((C , l , r , d)\),表示把数列中第\(l\sim r\)的数都加\(d\)
  • 第二类指令形如\((Q , X)\),表示询问数列中第\(x\)个数的值

两个操作区间增加和单点查询,输出每个单点查询

数据范围

\(1 \leq n,m \leq 10^{5}\)
\(| d | \leq 10000\)
\(A\left[ i\right] \leq 10^{9}\)

题解

  • 维护差分树状数组,用树状数组把所有差分的操作记在\(b\)数组中
  • 对于每条指令\((C , l , r , d)\),让 \(b \left[l\right] += d\)\(b\left[r+1\right] -= d\)
  • \(b\left[1~\sim x \right]\)的前缀和就是\(x\)上的所有操作的累加 , 即偏移量,每次查询的时候原始值加上偏移的量即可

Code

#include<bits/stdc++.h>
using namespace std;

#define rep(i, a, n) for(int i = a; i < n; i ++)

const int N = 1e5 + 10;

int c[N], a[N];
int n, m;

int lowbit(int x) { return x&-x; }

void add(int x, int y) {
    for(int i = x; i <= n; i += lowbit(i))
        c[i] += y;
}
int query(int x){
    int res = 0;
    for(int i = x; i; i -= lowbit(i))
        res += c[i];
        return res;
}
int main() {
    cin>>n>>m;
    rep(i, 1, n+1) cin>>a[i];
    char op[2];
    int l, r, d, x;
    while(m--){
        cin>>op;
        if(op[0] == 'C'){
            cin>>l>>r>>d;
            add(l, d); add(r + 1, -d);
        } else{
            cin>>x;
            cout<<a[x] + query(x)<<endl;
        }
    }
}

posted @ 2020-05-20 21:25  Hyx'  阅读(167)  评论(0)    收藏  举报