AcWing 242. 一个简单的整数问题
原题链接
简单
作者:
何以解忧唯有AC
,
2020-10-06 15:45:01
,
所有人可见
,
阅读 324
/*
将原数组改写成差分数组,那么修改[l,r]区间的值就是对差分数组单点修改,求单点的值就是对差分数组求前缀和
差分:a是原数组,b是差分数组, a[0] == 0
b[1] = a[1] - a[0]; a[1] = b[1]
b[2] = a[2] - a[1]; a[2] = b[1] + b[2];
b[3] = a[3] - a[2]; a[3] = b[1] + b[2] + b[3];
.
.
.
b[n] = a[n] - a[n-1] a[n] = b[1] + b[2] +...+ b[n]
对a[l ~ r]上加c, 即b[l] += c, b[r + 1] -= c;
例如:[1,3]
b[1] = a[1] + c;
b[2] = a[2] + c - (a[1] + c) = a[2] - a[1];
b[3] = a[3] + c - (a[2] + c) = a[3] - a[2];
b[4] = a[4] - (a[3] + c) = a[4] - a[3] - c;
b[5] = a[5] - a[4];
*/
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
int n, m;
int a[N], tr[N];
int lowbit(int x)
{
return x & -x;
}
void add(int x, int c)
{
for (int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}
LL sum(int x)
{
LL res = 0;
for (int i = x; i; i -= lowbit(i)) res += tr[i];
return res;
}
int main()
{
scanf("%d%d",&n, &m);
for (int i = 1; i <= n; i ++) scanf("%d",&a[i]);
//将差分数组存入树状数组中
for (int i = 1; i <= n; i ++) add(i, a[i] - a[i - 1]);
while(m --)
{
char op[2];
int l, r, d;
scanf("%s%d",op,&l);
if(op[0] == 'C')
{
scanf("%d%d", &r ,&d);
add(l, d), add(r + 1, -d);
}
else
{
printf("%lld\n",sum(l));
}
}
return 0;
}