【玄关】线段树求助 91pts
查看原帖
【玄关】线段树求助 91pts
1115392
small_moon楼主2024/7/13 17:47

代码如下

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int read();
struct Node {
	int v, left, right, tag;
}t[4*N];
int n, m;
int v[N];
void pushup(int k)
{
	t[k].v = t[k * 2].v + t[k * 2 + 1].v;
}
void f(int k, int v)
{
	t[k].v += (t[k].right - t[k].left + 1) * v;
	t[k].tag += v;
}
void pushdown(int k)
{
	f(k * 2, t[k].tag);
	f(k * 2 + 1, t[k].tag);
	t[k].tag = 0;
}
void build(int k, int l, int r)
{
	t[k].left = l; t[k].right = r;
	if (l == r)
	{
		t[k].v = v[l];
		return;
	}
	int mid = l + r >> 1;
	build(k * 2, l, mid); build(k * 2 + 1, mid + 1, r);
	pushup(k);
}
void update(int k, int l, int r, int v)
{
	if (t[k].left >= l && t[k].right <= r)
	{
		f(k, v);
		return;
	}
	pushdown(k);
	int mid = t[k].left + t[k].right >> 1;
	if (l <= mid) update(k * 2, l, r, v);
	if (r > mid) update(k * 2 + 1, l, r, v);
	pushup(k);
}
int query(int k, int l, int r)
{
	if (t[k].left >= l && t[k].right <= r) return t[k].v;
	pushdown(k);
	int mid = t[k].left + t[k].right >> 1, ret = 0;
	if (l <= mid) ret += query(k * 2, l, r);
	if (r > mid) ret += query(k * 2 + 1, l, r);
	return ret;
}
int main()
{
	n = read(); m = read();
	for (int i = 1; i <= n; i++) v[i] = read();
	for (int i = n; i >= 1; i--)
		v[i + 1] = v[i + 1] - v[i];
	build(1, 1, n);
	for (int i = 1; i <= m; i++)
	{
		int opt = read();
		if (opt == 1)
		{
			int l = read(), r = read(), k = read(), d = read();
			update(1, l, l, k);
			if (l + 1 <= r) update(1, l + 1, r, d);
			if (r < n) update(1, r + 1, r + 1, -(k + (r - l) * d));
		}
		if (opt == 2)
		{
			int p = read();
			printf("%d\n", query(1, 1, p));
		}
	}
	return 0;
}
int read()
{
	int x = 0, flag = 1; char ch = getchar();
	while (!isdigit(ch)) { if (ch == '-') flag = -1; ch = getchar(); }
	while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
	return x * flag;
}
2024/7/13 17:47
加载中...