线段树板子求条,玄关
  • 板块灌水区
  • 楼主_ScreamBrother_
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/11/4 21:58
  • 上次更新2024/11/5 08:45:25
查看原帖
线段树板子求条,玄关
1047636
_ScreamBrother_楼主2024/11/4 21:58
#include <bits/stdc++.h>
#define int long long

const int MAXN = 1e5 + 10;

struct Node { int left, right, lazy_tag, sum; };

std::vector <Node> seg_Tree (MAXN * 4);
std::vector <int> nums (MAXN * 4);
int N, M, x, y, k, op;

int len(int node) { return seg_Tree[node].right - seg_Tree[node].left + 1; }
int lch(int node) { return node * 2; }
int rch(int node) { return node * 2 + 1; }

void build(int left, int right, int node) {
	seg_Tree[node].left = left, seg_Tree[node].right = right;
	seg_Tree[node].lazy_tag = 0;
	if (left == right) {
		seg_Tree[node].sum = nums[left];
		return;
	}
	
	int mid = (right + left) / 2, lchild = node * 2, rchild = node * 2 + 1;
	build(left, mid, lchild), build(mid + 1, right, rchild);
	seg_Tree[node].sum = seg_Tree[lchild].sum + seg_Tree[rchild].sum;
}

void push_down(int node) {
	int lazy = 0;
	if ((lazy = seg_Tree[node].lazy_tag)) {
		int lchild = lch(node), rchild = rch(node), le = len(node);
		seg_Tree[node].sum += (le * seg_Tree[node].lazy_tag);
		seg_Tree[lchild].lazy_tag += lazy, seg_Tree[rchild].lazy_tag += lazy;
		int le1 = len(lchild), le2 = len(rchild);
		seg_Tree[lchild].sum += le1 * lazy, seg_Tree[rchild].sum += le2 * lazy;
		seg_Tree[node].lazy_tag = 0;
	}
}

void update(int left, int right, int tag, int node) {
	if (left <= seg_Tree[node].left && seg_Tree[node].right <= right) {
		seg_Tree[node].sum += len(node) * tag, seg_Tree[node].lazy_tag += tag;
		return;
	}
	
	push_down(node);
	
	int mid = (seg_Tree[node].left + seg_Tree[node].right) / 2;
	if (left <= mid) update(left, right, tag, 2 * node);
	if (mid < right) update(left, right, tag, 2 * node + 1);
	seg_Tree[node].sum = seg_Tree[node * 2].sum + seg_Tree[node * 2 + 1].sum;
}

int query(int left, int right, int node) {
	int ans = 0;
	if (left <= seg_Tree[node].left && seg_Tree[node].right <= right) 
		return seg_Tree[node].sum;
	
	push_down(node);
	
	int mid = (seg_Tree[node].left + seg_Tree[node].right) / 2;
	if (left <= mid) ans += query(left, right, 2 * node);
	if (mid < right) ans += query(left, right, 2 * node + 1);
	return ans;
}

signed main() {
	std::cin >> N >> M;
	for (int i = 1; i <= N; i ++) std::cin >> nums[i];
	build(1, N, 1);
	
	while (M --) {
		std::cin >> op;
		if (op == 1) {
			std::cin >> x >> y >> k;
			update(x, y, k, 1);
		} else {
			std::cin >> x >> y;
			std::cout << query(x, y, 1) << "\n";
		}
	}
	
	return 0;
}
2024/11/4 21:58
加载中...