题解:P13976 数列分块入门 1
yangjinqian · · 题解
题意
给一个长度为
-
若
opt = 0 表示将位于[l, r] 的之间的数字都加 c。 -
若
opt = 1 表示询问a_{r} 的值。
思路
虽然但是这个题可以用线段树或者树状数组做,但因为名字所以就用分块了。
基本思想:分块是一种暴力数据结构,它将数列分成
对于修改,将
对于询问,答案就是这个位置在当前数列中的值,加上它所在区间的
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e6 + 10;
ll n, len;
ll a[N], id[N], add[N];
void modify(ll l, ll r, ll c){
if (id[l] == id[r]){
for (ll i = l; i <= r; i++) a[i] += c;
return;
}
for (ll i = l; i <= min(id[l] * len, n); i++) a[i] += c;
for (ll i = id[l] + 1; i < id[r]; i++) add[i] += c;
for (ll i = min(id[r] * len - len + 1, n); i <= r; i++) a[i] += c;
}
int main(){
cin >> n;
len = sqrt(n);
for (ll i = 1; i <= n; i++) cin >> a[i], id[i] = (i - 1) / len + 1;
for (ll i = 1; i <= n; i++){
ll op, l, r, c;
cin >> op >> l >> r >> c;
if (!op) modify(l, r, c);
else cout << a[r] + add[id[r]] << endl;
}
}