关于线段树板子。
  • 板块学术版
  • 楼主ivnilkkk
  • 当前回复4
  • 已保存回复4
  • 发布时间2024/3/7 22:57
  • 上次更新2024/3/8 15:25:22
查看原帖
关于线段树板子。
1073341
ivnilkkk楼主2024/3/7 22:57

给一个长度为 nn 的序列,一开始每个位置的元素为 a[i]a[i],有 mm 次操作,每次操作将 [x,y][x,y] 减去 dd,如果当前线段树中有位置小于 00 了,那么就结束并输出当前操作的编号。

(简化自某道黄题。)

那么,我的代码为什么不对呢?求调,感谢!(不长,且都是板子。)

#include <bits/stdc++.h>
#define int long long
#define ls p << 1
#define rs p << 1 | 1
using namespace std;

const int N = 1e6+10;
int n, m, a[N], d, x, y, t[N*4];
bool ok;

void build(int p, int l, int r) {
	if(l == r) t[p] = a[l];
	else {
		int mid = (l + r) / 2;
		build(ls, l, mid);
		build(rs, mid + 1, r);
		t[p] = t[ls] + t[rs];
	}
}

void modify(int p, int l, int r, int x, int y, int k) {
	if(x <= l && r <= y) {
		t[p] += k * (r - l + 1);
		if(t[p] < 0) ok = false;
	} else {
		int mid = (l + r) / 2;
		if(x <= mid) modify(ls, l, mid, x, y, k);
		if(y > mid) modify(rs, mid + 1, r, x, y, k);
		t[p] = t[ls] + t[rs];
		if(t[p] < 0) ok = false;
	}
}

signed main() {
//	freopen("in.txt", "r", stdin);
//	freopen("out.txt", "w", stdout);
	scanf("%lld%lld", &n, &m);
	for(int i = 1; i <= n; i++)
		scanf("%lld", &a[i]);
	build(1, 1, n);
	for(int i = 1; i <= m; i++) {
		scanf("%lld%lld%lld", &d, &x, &y);
		ok = true;
		modify(1, 1, n, x, y, -d);
		if(!ok) {
			printf("-1\n%lld\n", i);
			return 0;
		}
	}
	printf("0\n");
	return 0;
}
2024/3/7 22:57
加载中...