线段树板子,救,全WA
查看原帖
线段树板子,救,全WA
118196
zimujun楼主2020/9/23 11:06

不熟悉线段树,今天来敲个板子,然后漂亮的写挂了

区间修改和单点查询没有问题,因为过了树状数组2

目前推测是因为标记下放挂了

#include<bits/stdc++.h>
#define LL long long
#define ls t << 1
#define rs t << 1 | 1
#define MID (l + r) >> 1

using namespace std;

const int Maxn = 5e5 + 5;

struct e{
	LL data;
	int tag;
};
e a[Maxn << 2];
LL num[Maxn];

int n, m, opt, x, y;
LL del;

void pushup(int t)
{
	a[t].data = a[ls].data + a[rs].data;
}

void pushdown(int l, int r, int t)
{
	a[t].data += (r - l + 1) * a[t].tag;
	a[ls].tag += a[t].tag;
	a[rs].tag += a[t].tag;
	a[t].tag = 0;
}

void build(int l, int r, int t)
{
	if(l == r)
	{
		a[t].data = num[l];
		return;
	}
	int mid = MID;
	build(l, mid, ls);
	build(mid + 1, r, rs);
	pushup(t);
}

LL query(int lf, int rt, int l, int r, int t)
{
	if(a[t].tag)
	{
		pushdown(l, r, t);
	}
	if(lf <= l && r <= rt) return a[t].data;
	int mid = MID;
	LL sum;
	if(rt <= mid) sum = query(lf, rt, l, mid, ls);
	else if(lf > mid) sum = query(lf, rt, mid + 1, r, rs);
	else sum = query(lf, mid, l, mid, ls) + query(mid + 1, rt, mid + 1, r, rs);
	if(l < r) pushup(t);
	return sum;
}

void update(int lf, int rt, LL delta, int l, int r, int t)
{
	if(lf <= l && r <= rt)
	{
		a[t].tag += delta;
		pushdown(l, r, t);
	}
	else
	{
		if(a[t].tag) pushdown(l, r, t);
		int mid = MID;
		if(rt <= mid) update(lf, rt, delta, l, mid, ls);
		else if(lf > mid) update(lf, rt, delta, mid + 1, r, rs);
		else
		{
			update(lf, mid, delta, l, mid, ls);
			update(mid + 1, rt, delta, mid + 1, r, rs);
		}
	}
	if(l < r) pushup(t);
}

inline LL read()
{
	LL f = 1, w = 0; char ch = getchar();
	for(;(ch < '0') || (ch > '9'); ch = getchar()) if(ch == '-') f = -1;
	for(;(ch >= '0') && (ch <= '9'); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
	return f * w;
}
inline int read0()
{
	int f = 1, w = 0; char ch = getchar();
	for(;(ch < '0') || (ch > '9'); ch = getchar()) if(ch == '-') f = -1;
	for(;(ch >= '0') && (ch <= '9'); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
	return f * w;
}

int main()
{
	n = read0(); m = read0();
	for(int i = 1; i <= n; ++i)
	{
		num[i] = read0();
	}
	build(1, n, 1);
	while(m--)
	{
		opt = read0();
		if(opt == 1)
		{
			x = read0(); y = read0(); del = read();
			update(x, y, del, 1, n, 1);
		}
		else
		{
			x = read0(); y = read0();
			printf("%lld\n", query(x, y, 1, n, 1));
		}
	}
	return 0;
}
2020/9/23 11:06
加载中...