题目链接:A Simple Problem with Integers
装模作样的题目
装模作样的解题思路
这道题其实是线段树(完全不知道线段树的同学从头学起叭)的 区间修改
的模板题
懂得线段树区间查询的同学其实很好操作(不懂得话先看看线段树的基础操作吧)。
区间修改跟区间查询有点类似,为了节约时间,我们添加一个懒标记
…惹~懒得写了,区间修改不太知道的同学去看猹的博客吧
注意事项!!!
我认为,可能是我见识短。。。我认为这道题有毒
我的数组原本开的是 2e5 + 9
结果一直 WA
后来我对比了以前 AC 的代码(对了我现在算是在复建),发现没有差别,唯一的就是 AC 代码的范围是 1e5 + 9
。。。
然后过了???头一次知道数组开太大也能当作 WA 的理由
就酱~继续走流程
装模作样的代码
#include <iostream>
using namespace std;
typedef long long uio;
#include <vector>
const uio maxn = uio(1e5 + 9);
#define DEFI_ST uio l, uio r, uio t
#define INIT_ST 1, n, 1
#define MIND_ST uio m = (l + r) >> 1
#define WIDE_ST uio w = r - l + 1
#define LSON_ST l, m, t << 1
#define RSON_ST m + 1, r, t << 1 | 1
vector<uio> orig(maxn), tree(maxn << 2), lazy(maxn << 2);
void push_up(uio t) {tree[t] = tree[t << 1] + tree[t << 1 | 1];}
void push_down(uio a, uio b, uio t) {
if (lazy[t]) {
lazy[t << 1] += lazy[t];
tree[t << 1] += lazy[t]*a;
lazy[t << 1 | 1] += lazy[t];
tree[t << 1 | 1] += lazy[t]*b;
lazy[t] = 0;
}
}
void build(DEFI_ST) {
lazy[t] = 0;
if (l == r) {tree[t] = orig[l]; return ;}
MIND_ST;
build(LSON_ST);
build(RSON_ST);
push_up(t);
}
void update(uio pl, uio pr, uio n, DEFI_ST) {
WIDE_ST;
if (pl <= l && pr >= r) {
lazy[t] += n;
tree[t] += n*w;
return ;
}
push_down(w - (w >> 1), w >> 1, t);
MIND_ST;
if (pl <= m) update(pl, pr, n, LSON_ST);
if (pr > m) update(pl, pr, n, RSON_ST);
push_up(t);
}
uio query(uio ql, uio qr, DEFI_ST) {
if (ql <= l && qr >= r) return tree[t];
WIDE_ST;
push_down(w - (w >> 1), w >> 1, t);
MIND_ST, s = 0;
if (ql <= m) s += query(ql, qr, LSON_ST);
if (qr > m) s += query(ql, qr, RSON_ST);
return s;
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
uio n, t; while (cin >> n >> t) {
for (uio i = 1; i <= n; i++) cin >> orig[i];
build(INIT_ST);
while (t--) {
string o; uio a, b;
cin >> o >> a >> b;
if (o[0] == 'C') {uio c; cin >> c; update(a, b, c, INIT_ST);}
if (o[0] == 'Q') cout << query(a, b, INIT_ST) << endl;
}
}
return 0;
}