大佬救命
查看原帖
大佬救命
768692
InoriILU楼主2023/7/18 12:23
#include <iostream>

typedef long long NodeType;
typedef long long DataType;

const int MAXN{ 100000 + 5 };

DataType value[MAXN]{};
DataType tree[MAXN * 4]{};
DataType tag[MAXN * 4]{};
NodeType size{};

void build(NodeType left = 1, NodeType right = size, NodeType now = 1)
{
	if (left == right) //到达叶子节点
	{
		tree[now] = value[left]; //赋值
	}
	else
	{
		NodeType mid = (left + right) / 2;
		build(left, mid, now * 2);
		build(mid + 1, right, now * 2 + 1); //左右节点递归建立
		tree[now] = tree[now * 2] + tree[now * 2 + 1]; //本节点等于儿子
	}
};//
void pushdown(NodeType now, NodeType length)
{
	tag[now * 2] += tag[now];
	tag[now * 2 + 1] += tag[now];
	tree[now * 2] += tag[now] * (length - length / 2); //以区间长度定义儿子节点的权值相加量
	tree[now * 2 + 1] += tag[now] * (length / 2);
	tag[now] = 0;
};//
void update(NodeType _left, NodeType _right, DataType value, NodeType now = 1, NodeType c_left = 1, NodeType c_right = size)
{
	if (_right < c_left || c_right < _left) //无交集,注意符号方向
	{
		return;
	}
	else if (_left <= c_left && c_right <= _right) //包含关系
	{
		tree[now] += (c_right - c_left + 1) * value;
		if (c_right > c_left)
		{
			tag[now] += value;   
		}
	}
	else //有交集不完全包含
	{
		NodeType mid{ (c_left + c_right) / 2 };
		pushdown(now, c_right - c_left + 1);
		update(_left, _right, value, now * 2, c_left, mid);
		update(_left, _right, value, now * 2 + 1, mid + 1, c_right);
		tree[now] = tree[now * 2] + tree[now * 2 + 1];
	}
};

DataType query(NodeType _left, NodeType _right, NodeType now = 1, NodeType c_left = 1, NodeType c_right = size)
{
	if (_right < c_left || c_right < _left)
	{
		return false;
	}
	else if (_left <= c_left && c_right <= _right)
	{
		return tree[now];
	}
	else
	{
		NodeType mid{ (c_left + c_right) / 2 };
		NodeType length{ c_right - c_left + 1 };
		pushdown(now, length);
		return query(_left, _right, now * 2, c_left, mid) + query(_left, _right, now * 2 + 1, mid + 1, c_right);
	}
};

int main()
{
	using namespace std;
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	int T{}, o{}, l{}, r{}, k{};
	cin >> ::size >> T;
	for (int i = 0; i < ::size; i++)
	{
		cin >> value[i];
	}
	build();
	while (T--)
	{
		cin >> o >> l >> r;
		if (o == 1)
		{
			cin >> k;
			update(l, r, k);
		}
		else
		{
			cout << query(l, r) << "\n";
		}
	}
}

2023/7/18 12:23
加载中...