题目描述
给出一个长为 的数列,以及 个操作,操作涉及区间加法,单点查值。

输入格式
第一行输入一个数字 。

第二行输入 个数字,第 个数字为 ,以空格隔开。

接下来输入 行询问,每行输入四个数字 、、、,以空格隔开。

若 ,表示将位于 的之间的数字都加 。

若 ,表示询问 的值( 和 忽略)。

输出格式
对于每次询问,输出一行一个数字表示答案。

样例
样例输入
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;
}
 posted on 2019-04-27 15:38  谁是凶手1703  阅读(71)  评论(0)    收藏  举报