社区讨论

线段树求调

灌水区参与者 6已保存回复 12

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
11 条
当前快照
1 份
快照标识符
@lzi5z1c7
此快照首次捕获于
2024/08/06 16:34
2 年前
此快照最后确认于
2024/08/06 17:14
2 年前
查看原帖
C
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e6 + 100;
int n,m,opt,x,y,k;
int a[maxn],sum[maxn],addv[maxn];
void build (int o,int l,int r){
	if (l == r) sum[o] = a[l];
	else{
		int mid = l + (r - l) / 2;
		build (o * 2,l,mid);
		build (o * 2 + 1,mid + 1,r);
		sum[o] = sum[o * 2] + sum[o * 2 + 1];
	}
}
void update (int o,int l,int r){
	if (l == r) {
		addv[o] += k;
		sum[o] += k;
	}else{
		int mid = l + (r - l) / 2;
		if (x <= mid) update (o * 2,l,mid);
		else update (o * 2 + 1,mid + 1,r);
		sum[o] = sum[o * 2] + sum[o * 2 + 1] + (r - l + 1) * k;
    }
}
int find (int o,int l,int r){
	if (x <= l && r <= y) return (sum[o] + (r - l + 1) * addv[o]);
	int ans = 0;
	int mid = l + (r - l) / 2;
	if (x <= mid) ans += (find (o * 2,l,mid) + (min(r,y) - max(l,x) + 1) * addv[o]);
	if (y > mid) ans += (find (o * 2 + 1,mid + 1,r) + (min(r,y) - max(l,x) + 1) * addv[o]);
	return ans;
}
int main(){
	cin >> n >> m;
	for (int i = 1 ; i <= n ; i++) cin >> a[i];
	build (1,1,n);
	for (int i = 1 ; i <= m ; i++){
		cin >> opt >> x >> y;
		if (opt == 1){
			cin >> k;
			update (1,1,n);
		}else{
			cout << find (1,1,n) << endl;
		}
	}
	return 0;
}
该程序样例输出:11 6 20
正确输出:11 8 20
P3372

回复

12 条回复,欢迎继续交流。

正在加载回复...