线段树求助 Debug

题目描述

给你 n 个整数,请问第 x 个到第 y 个的和是多少?

在询问前后,这 n 个数中的某个区间的数可能会同时变成 z。

输入

第一行:n 和 m,表示 n 个数,m 个询问。

第二行:n 个整数。

接下来 m 行,每行3 或 4 个整数 o、x、y(、z):o 表示求和还是更改数字,如果 o=1,表示第 x 个数到第 y 个数都变成 z;如果 o = 2,表示求第 x 个到第 y 个的和。

输出

对于每次询问和,输出区间的和。

样例输入

5 3
1 2 -3 6 5
2 2 4
1 2 5 1
2 1 3

样例输出

5
3

数据范围

1<=x、y<=n;1<=o<=2;n 个数,每个数的绝对值不超过 1000;5<=n、m<=200000。

WA 40pts,代码如下:

#include <bits/stdc++.h>
using namespace std;
#define int long long 

const int N = 2e5 + 5;
int n, q, op, l, r, x, a[N], s[4 * N], b[4 * N];

void build(int i, int l, int r) // 建树 
{
	if (l == r) s[i] = a[r];
	else
	{
		int m = l + r >> 1;
		build(i << 1, l, m);
		build((i << 1) + 1, m + 1, r);
		s[i] = s[i << 1] + s[(i << 1) + 1];
	 }
}

void add(int i, int l, int r, int x, int y, int d) // 区间 [x,y] 每个数改为 d
{
	if (x <= l && r <= y) s[i] = (r - l + 1) * d, b[i] = d;
	else
	{
		int m = l + r >> 1;
		if (b[i])
		{
			s[i << 1] = b[i] * (m - l + 1), s[(i << 1) + 1] = b[i] * (r - m);
			b[i << 1] = b[i], b[(i << 1) + 1] = b[i], b[i] = 0;
		}
		if (x <= m) add(i << 1, l, m, x, y, d);
		if (y > m) add((i << 1) + 1, m + 1, r, x, y, d);
		s[i] = s[i << 1] + s[(i << 1) + 1]; 
	}
}

int sum(int i, int l, int r, int x, int y) // 求区间 [x,y] 的和 
{
	if (x <= l && r <= y) return s[i];
	int m = l + r >> 1, res = 0;
	if (b[i])
	{
		s[i << 1] = b[i] * (m - l + 1), s[(i << 1) + 1] = b[i] * (r - m);
		b[i << 1] = b[i], b[(i << 1) + 1] = b[i], b[i] = 0;
	}
	if (x <= m) res += sum(i << 1, l, m, x, y);
	if (y > m) res += sum((i << 1) + 1, m + 1, r, x, y);
	return res; 
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> q;
	for (int i = 1; i <= n; i++) cin >> a[i];
	build(1, 1, n);
	while (q--)
	{
		cin >> op >> l >> r;
		if (op == 1)
		{
			cin >> x;
			add(1, 1, n, l, r, x);
		}
		else cout << sum(1, 1, n, l, r) << "\n"; 
	}
	return 0;
}

全部评论
求调代码qwq
点赞 回复 分享
发布于 05-26 13:35 广东

相关推荐

评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务