求助线段树(悬赏关注)
查看原帖
求助线段树(悬赏关注)
236314
_siyuanke_楼主2022/10/27 20:02
#include<bits/stdc++.h>

using namespace std;

const int MAXN = 1000010;

int a[MAXN]; //输入数组

int Ans;

struct
{
	int l, r; //表示某个节点代表的区间
	int sum; //区间和,也可以区间最大最小值
	int lz; //懒惰标记
}tree[MAXN];

void build(int i, int l, int r) //通用
{
	tree[i].l = l, tree[i].r = r;
	if(l == r)
	{
		tree[i].sum = a[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(i * 2, l, mid);
	build(i * 2 + 1, mid + 1, r);
	tree[i].sum = tree[i * 2].sum + tree[i * 2 + 1].sum;
}

void push_down(int i) //把懒惰标记向下移
{
	if(tree[i].lz != 0)
	{
		tree[i * 2].lz += tree[i].lz;
		tree[i * 2 + 1].lz += tree[i].lz;
		int mid = (tree[i].l + tree[i].r) / 2;
		tree[i * 2].sum += tree[i].lz * (mid - tree[i].l + 1);
		tree[i * 2 + 1].sum += tree[i].lz * (tree[i].r - mid); //千万不要再加1了
		tree[i].lz = 0;
		//不用将sum清空
	}
	return;
}

void add(int i, int l, int r, int k) //区间修改
{
	if(tree[i].l >= l && tree[i].r <= r)
	{
		tree[i].sum += k * (tree[i].r - tree[i].l + 1);
		tree[i].lz += k; //向下传递懒惰标记
		return;
	}
	push_down(i);
	if(tree[i * 2].r >= l) add(i * 2, l, r, k);
	if(tree[i * 2 + 1].l <= r) add(i * 2 + 1, l, r, k);
	tree[i].sum = tree[i * 2].sum + tree[i * 2 + 1].sum; //有关区间的add要加上这个
}

int get_sum(int i, int l, int r) //区间查询
{
	if(tree[i].l >= l && tree[i].r <= r)
		return tree[i].sum;
	if(tree[i].r < l || tree[i].l > r)
		return 0;
	push_down(i);
	
	int res = 0;
	if(tree[i * 2].r >= l) res += get_sum(i * 2, l, r);
	if(tree[i * 2 + 1].l <= r) res += get_sum(i * 2 + 1, l, r);
	return res;
}

int main()
{
	int n, t, op, x, y, z;
	cin >> n >> t;
	for(int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	build(1,1,n);
	while(t--)
	{
		cin >> op;
		if(op == 1)
		{
			cin >> x >> y >> z;
			add(1, x, y, z);
		}
		else
		{
			cin >> x >> y;
			cout << get_sum(1, x, y) << endl;
		}
	}
    return 0;
}

8 9 10三个点WA了

2022/10/27 20:02
加载中...