题目描述
给出一个长为 的数列,以及 个操作,操作涉及区间加法,单点查值。
输入格式
第一行输入一个数字 。
第二行输入 个数字,第 个数字为 ,以空格隔开。
接下来输入 行询问,每行输入四个数字 、、、,以空格隔开。
若 ,表示将位于 的之间的数字都加 。
若 ,表示询问 的值( 和 忽略)。
输出格式
对于每次询问,输出一行一个数字表示答案。
样例
样例输入
4
1 2 2 3
0 1 3 1
1 0 1 0
0 1 2 2
1 0 2 0
样例输出
2
5
//#define fre yes
#include<bits/stdc++.h>
using namespace std;
const int MAXN_INT = 50005;
int belong[MAXN_INT], l[MAXN_INT], r[MAXN_INT], Lazy[MAXN_INT], arr[MAXN_INT];//lazy 记录整块的上层操作
int num, black;
//单点数值=pos数值+ lazy的上层操作
void build(int n) {
black = sqrt(n);
num = n / black;
if(n % black) num++;
for (int i = 1; i <= num; i++) {
l[i] = (i - 1) * black + 1, r[i] = i * black;
} r[num] = n;
for (int i = 1; i <= n; i++) {
belong[i] = (i - 1) / black + 1;
}
}
void update(int x, int y, int val) {
if(belong[x] == belong[y]) {
for (int i = x; i <= y; i++) {
arr[i] += val;
}
}
if(belong[x] != belong[y]) {
for (int i = x; i <= r[belong[x]]; i++) {
arr[i] += val;
}
for (int i = belong[x] + 1; i <= belong[y] - 1; i++) {
Lazy[i] += val;
}
for (int i = l[belong[y]]; i <= y; i++) {
arr[i] += val;
}
}
}
int main() {
int n;
ios::sync_with_stdio(false);
cin>>n;
for (int i = 1; i <= n; i++) {
cin>>arr[i];
}
build(n);
for (int i = 1; i <= n; i++) {
int opt, le, re, c;
cin>>opt>>le>>re>>c;
if(opt == 0) {
update(le, re, c);
} if(opt == 1) {
cout<< arr[re] + Lazy[belong[re]]<<endl;
}
} return 0;
}