社区讨论
为什么我的线段树空间要开八倍才能通过?
学术版参与者 5已保存回复 7
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 6 条
- 当前快照
- 1 份
- 快照标识符
- @mkgy8798
- 此快照首次捕获于
- 2026/01/16 22:03 上个月
- 此快照最后确认于
- 2026/01/19 14:10 上个月
为什么我的线段树空间要开八倍才能通过?
代码:
CPP#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, m;
long long a[N];
struct node {
int l, r;
long long w, tag;
}tr[N << 3];
void pushup (int u) {
tr[u].w = tr[u << 1].w + tr[u << 1 | 1].w;
}
void pushtag (int u, long long x, int lng) {
tr[u].tag += x;
tr[u].w += x * lng;
}
void pushdown (int u) {
int l = tr[u].l, r = tr[u].r, mid = l + r >> 1;
pushtag (u << 1, tr[u].tag, mid - l + 1);
pushtag (u << 1 | 1, tr[u].tag, r - mid);
tr[u].tag = 0;
}
void mktr (int u, int l, int r) {
tr[u].l = l, tr[u].r = r;
if (l == r) { tr[u].w = a[l]; return; }
int mid = l + r >> 1;
mktr (u << 1, l, mid); mktr (u << 1 | 1, mid + 1, r);
pushup (u);
}
long long query (int x, int y, int u) {
int l = tr[u].l, r = tr[u].r;
if (l > y || r < x) return 0;
pushdown (u);
if (l >= x && r <= y) return tr[u].w;
return query (x, y, u << 1) + query (x, y, u << 1 | 1);
}
void add (int x, int y, int u, long long k) {
int l = tr[u].l, r = tr[u].r;
if (l > y || r < x) return;
pushdown (u);
if (l >= x && r <= y) {
pushtag (u, k, r - l + 1);
return;
}
add (x, y, u << 1, k); add (x, y, u << 1 | 1, k);
pushup (u);
}
int main () {
// return 114514;
scanf ("%d %d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf ("%lld", a + i);
}
mktr (1, 1, n);
while (m--) {
int o, x, y;
scanf ("%d %d %d", &o, &x, &y);
if (o == 1) {
long long k;
scanf ("%lld", &k);
add (x, y, 1, k);
}
else {
printf ("%lld\n", query (x, y, 1));
}
}
return 0;
}
如果这份代码树的空间改成 的话会 RE 掉。
之前写的代码却能直接 AC:
CPP#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n, m, x, y;
long long tr[N << 2], lzy[N << 2], a[N], k;
void tag (int u, long long x, int len) {
tr[u] += x * len;
lzy[u] += x;
}
void pushup (int u){
tr[u] = tr[u << 1] + tr[u << 1 | 1];
}
void pushdown (int l, int r, int u){
int m = l + r >> 1;
tag (u << 1, lzy[u], m - l + 1);
tag (u << 1 | 1, lzy[u], r - m);
lzy[u]=0;
}
void mktr (int l, int r, int u){
if (l == r) {tr[u] = a[l]; return;}
int m = l + r >> 1;
mktr (l, m, u << 1);
mktr (m + 1, r, u << 1 | 1);
pushup (u);
}
bool in (int l, int r) {
return l >= x && r <= y;
}
bool mgx (int l, int r) {
return x > r || l > y;
}
long long sum (int u, int l, int r) {
if (in (l, r)) return tr[u];
if (mgx (l, r)) return 0;
pushdown (l, r, u);
int m = l + r >> 1;
return sum (u << 1, l, m) + sum (u << 1 | 1, m + 1 , r);
}
void jia (int u, int l, int r){
if (in (l, r)){
tag (u, k, r - l + 1);
}
else if (!mgx (l, r)){
pushdown (l, r, u);
int m = l + r >> 1;
jia (u << 1, l, m); jia (u << 1 | 1, m + 1, r);
pushup (u);
}
}
int main () {
scanf ("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
scanf ("%lld", &a[i]);
mktr (1, n, 1);
while (m--) {
int o;
scanf ("%d %d %d", &o, &x, &y);
if (o == 1) {
scanf ("%lld", &k);
jia (1, 1, n);
}
else printf ("%lld\n", sum (1, 1, n));
}
return 0;
}
呜呜呜,我之前闲着翻讨论区的时候看到别人问这个问题的,奈何没仔细看,没想到同样的问题又发生到我身上了。
回复
共 7 条回复,欢迎继续交流。
正在加载回复...