A Tiny Problem with intergers

给定长度为N的数列A,然后输入M行操作指令。

第一类指令形如“C l r d”,表示把数列中第l~r个数都加d。

第二类指令形如“Q X”,表示询问数列中第x个数的值。

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

输入格式

第一行包含两个整数N和M。

第二行包含N个整数A[i]。

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

输出格式

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

每个答案占一行。

数据范围

1N,M1051≤N,M≤105,
|d|10000|d|≤10000,
|A[i]|1000000000|A[i]|≤1000000000

输入样例:

10 5
1 2 3 4 5 6 7 8 9 10
Q 4
Q 1
Q 2
C 1 6 3
Q 2

输出样例:

4
1
2
5


区间加,单点查询,经典的树状数组题,具体做法是:先对数组进行差分运算,有结论差分的前缀和等于该位本身大小,在数组为差分的情况下,我们要给l~r加d,
只需add(l,d),add(r+1,-d)即可
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
#define form(i,n) for(int i=1;i<=n;i++)
#define forn(i,n) for(int i=0;i<n;i++)
#define mst(a) memset(a,0,sizeof(a))
#define P pair<int,int>
#define wh(T) while(T--)
const int MAX_N=1e7+10;
const int N=1e6+90;
const int inf=1e8;
int a[N],c[N],n,m,MAX=1e6;
int lowbit(int x){
    return x&-x;
}
void add(int x,int y){
    while (x<=MAX){
        c[x]+=y;
        x+=lowbit(x);
    }
}
int query(int x){
    int res=0;
    while (x){
        res+=c[x];
        x-=lowbit(x);
    }
    return res;
}
int main() {
    ios::sync_with_stdio(0);
    cin>>n>>m;
    int t;
    form(i,n){
        cin>>a[i];
    }
    form(i,n){
        add(i,a[i]-a[i-1]);
    }
    form(i,m){
        char c;
        cin>>c;
        int l,r,d;
        if(c=='C'){
            cin>>l>>r>>d;
            add(l,d);
            add(r+1,-d);
        }else{
            cin>>l;
            cout<<query(l)<<endl;
        }
    }
}
 

猜你喜欢

转载自www.cnblogs.com/ilikeeatfish/p/12970078.html