https://www.luogu.org/problemnew/show/P3368
//区间修改 单点查询
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
#define lowbit(x) (x&(-x)) //计算2^k
const int Max = 500000+5;
int c[Max];//c[i] = a[i – 2^k + 1] + … + a[i],k为i在二进制下末尾0的个数, a为猿给定数组(即初始化时给的值)
//单点修改,仅需修改c[i],求区间和直接用c[i]就可以了
void Update(int x, int y, int MAX)
{
while(x <= MAX){
c[x] += y;
x += lowbit(x);
}
}
//区间修改 (部分样例会发生 TLE)
/*void UpdateSQ(int x, int y, int k, int MAX)
{
while(x <= MAX){
c[x] += k;
x += lowbit(x);
}
while(y <= MAX){
c[y] -= k;
y += lowbit(y);
}
}
*/
//a[i-lowbit(i)]+......a[i] +.....a[i-lowbit(i)-lowbit(i-lowbit(i))]+.....a[i-lowbit(i)]+.....a[0]查询
int Sum(int x)
{
int sum = 0;
while(x > 0){
sum += c[x];
x -= lowbit(x);
}
return sum;
}
//区间查询
void SumSQ(int y, int x)
{
int sum = 0;
while(y > 0){
sum += c[y];
y -= lowbit(y);
}
while(x > 0){
sum -= c[x];
x -= lowbit(x);
}
// cout << sum << endl;
printf("%d\n", sum);
}
int main()
{
int T, cnt = 1;
string s;
//cin >> T;
// scanf("%d", &T);
//while(T--)
{
int N, m;
// cin >> N;
scanf("%d%d", &N, &m);
memset(c, 0, sizeof(c));
int tmp = 0;
for(int i=1; i<=N; i++){
int x;
scanf("%d", &x);
//区间修改需要用到差分......
Update(i, x-tmp, N); //差分 x-tmp相当于a[i]-a[i-1] 则Sum()所求结果相当于a[i]
tmp = x;
}
// cout << "Case " << cnt++ << ":" << endl;
// printf("Case %d:\n", cnt++);
for(int i=0; i<m; i++){
int q;
int x, y;
scanf("%d", &q);
// cin >> x >> y;
if(q == 1){
//区间修改
int k;
cin >> x >> y >> k;
// UpdateSQ(x, y+1, k, N);
Update(x, k, N);
Update(y+1, -k, N);
}
else {
cin >> x;
cout << Sum(x) << endl;
}
}
}
return 0;
}