Kaedehara_zgb @ 2023-10-20 09:48:32
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 100100;
int n, m, i, a[N], ans;
struct no {
int sum;
};
struct lazy {
int add;
};
struct node {
lazy t;
no val;
int len;
}seg[N * 4];
no operator + (const no &l, const no &r) {
return {l.sum + r.sum};
}
lazy operator + (const lazy &v, const lazy &t) {
return {v.add+ t.add};
}
void update(int id) {
seg[id].val.sum = seg[id * 2].val.sum + seg[id * 2 + 1].val.sum;
seg[id].len = seg[id * 2].len * 2;
}
void build(int id, int l, int r) {
if(l == r) {
seg[id].val.sum = a[l];
seg[id].len = 1;
return;
}
int mid = (l + r) / 2;
build(id * 2, l, mid);
build(id * 2 + 1, mid + 1, r);
update(id);
}
void setlazy(int id, lazy t) {
seg[id].val.sum = seg[id].val.sum + t.add * seg[id].len;
seg[id].t = seg[id].t + t;
}
void pushdown(int id) {
if(seg[id].t.add != 0) {
setlazy(id * 2, seg[id].t);
setlazy(id * 2 + 1, seg[id].t);
seg[id].t.add = 0;
}
}
int query(int id, int l, int r, int ql, int qr) {
if(l == qr && r == qr) return seg[id].val.sum;
int mid = (l + r) / 2;
pushdown(id);
if(qr <= mid) return query(id * 2, l, mid, ql, qr);
else if(ql > mid) return query(id * 2 + 1, mid + 1, r, ql, qr);
else return query(id * 2, l, mid, ql, mid) + query(id * 2 + 1, mid + 1, r, mid + 1, qr);
}
void modify(int id, int l, int r, int ql, int qr, lazy t) {
if(l == qr && r == qr) {setlazy(id, t); return;}
int mid = (l + r) / 2;
pushdown(id);
if(qr <= mid) return modify(id * 2, l, mid, ql, qr, t);
else if(ql > mid) return modify(id * 2 + 1, mid + 1, r, ql, qr, t);
else {
modify(id * 2, l, mid, ql, mid, t);
modify(id * 2 + 1, mid + 1, r, mid + 1, qr, t);
}
update(id);
}
signed main () {
scanf("%lld %lld", &n, &m);
for (i = 1; i <= n; ++i) scanf("%lld", &a[i]);
build(1, 1, n);
while(m--) {
int ty;
scanf("%lld", &ty);
if(ty == 1) {
int l, r, d;
scanf("%lld %lld %lld", &l, &r, &d);
modify(1, 1, n, l, r, (lazy){d});
} else {
int l, r;
scanf("%lld %lld",&l, &r);
ans = query(1, 1, n, l, r);
printf("%lld\n", ans);
}
}
}
我很难理解,题解没加标记没有超,我加了反而还超了,大佬帮忙看看问题在哪里。谢谢!
by gghack_Nythix @ 2023-10-20 10:08:22
查询区间不需要查到叶子节点上吧
by Buried_Dream @ 2023-10-20 10:09:36
if(l == qr && r == qr) return seg[id].val.sum;
这都查到叶子节点了吧
by kyEEcccccc @ 2023-10-20 10:25:52
@Buried_Dream 仔细看他的写法,不会查到叶子上。
TLE 的问题我不清楚,但是
if(qr <= mid) return modify(id * 2, l, mid, ql, qr, t);
else if(ql > mid) return modify(id * 2 + 1, mid + 1, r, ql, qr, t);
else {
modify(id * 2, l, mid, ql, mid, t);
modify(id * 2 + 1, mid + 1, r, mid + 1, qr, t);
}
update(id);
会导致你有时候不 update
,答案错误。
by kyEEcccccc @ 2023-10-20 10:26:20
@Kaedehara_zgb
by Buried_Dream @ 2023-10-20 10:35:52
@Retired_kyEEcccccc 为什么他这个会有的时候不 update,退役人看不出来了/kk
by Kaedehara_zgb @ 2023-10-20 10:36:24
@Retired_kyEEcccccc 就只有超时没有答案错误
by kyEEcccccc @ 2023-10-20 10:42:36
@Buried_Dream 上两行 return
了
by Buried_Dream @ 2023-10-20 10:42:55
@Retired_kyEEcccccc
l == qr && r == qr
那 l应该等于r吧,我感觉查到叶子节点了
by Kaedehara_zgb @ 2023-10-20 10:44:27
@Retired_kyEEcccccc 了解,改好了,因为modify是复制query的忘记删return了。但还是超的![结果] O2开了也是这样
by Buried_Dream @ 2023-10-20 10:45:12
@Retired_kyEEcccccc
我大概明白了,他TLE的原因就是因为都查到叶子节点了,然后没update所以答案错了