题目
题解思路
我们把原数组保存,把树状数组看成原数组要加的数的差分数组 , 对要加减的区间只需在首部加上目标值,在尾部的后一位减去目标值。
由差分可以知道,对差分数组求前缀和就是原数组的值。
而快速求前缀和正好是树状数组的性质之一。
求这部分的前缀和,就可以得出要加多少数,然后加上原数就行了。
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
#include <unordered_map>
using namespace std;
const int INF = 0x3f3f3f3f;
long long tre[100010] ;
long long a[100010] ;
int n , m ;
int lowbit( int x )
{
return x & (-x) ;
}
void add1(int x , int y )
{
for (int i = x ; i <= n ; i += lowbit(i) )
tre[i] += y ;
}
long long sum( int x )
{
long long res = a[x] ;
for (int i = x ; i ; i -= lowbit(i) )
res += tre[i] ;
return res ;
}
int main ()
{
ios::sync_with_stdio(false);
cin >> n >> m ;
for (int i = 1 ; i <= n ; i++ )
cin>>a[i];
for (int i = 1 ; i <= m ; i++ )
{
string t1 ;
int t2 , t3 , t4 ;
cin>>t1;
if ( t1[0] == 'Q')
{
cin >> t2 ;
cout << sum(t2) <<"\n";
}else
{
cin >> t2 >> t3 >> t4 ;
add1( t2 , t4 );
add1( t3 + 1 , -t4 );
}
}
return 0 ;
}