NOWCODER Tree Recovery(线段树)

链接:https://ac.nowcoder.com/acm/problem/15175
来源:牛客网
在这里插入图片描述
在这里插入图片描述

题意:

输入Q代表求从x到y的和,输入C代表从a到b位置的数都加上c

思路:

树状数组,线段树模板,区间更新,区间求和。

AC代码:

#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
ll A[maxn],a,b,c,sum[maxn*4],add[maxn*4],n,m;
char ch;

//下推标记
void pushDown(int node,int m) {
	if(add[node]) {
		add[node*2] += add[node];
		add[node*2+1] += add[node];
		sum[node*2] += add[node]*(m-m/2);
		sum[node*2+1] += add[node]*(m/2);
		add[node] = 0;
	}
} 
//建树
void build(int l,int r,int node) {
	add[node]=0;
	if(l==r) {
		sum[node]=A[l];
		return;
	}
	int mid = (l+r)/2;
	build(l,mid,node*2); 
	build(mid+1,r,node*2+1);
	sum[node] = sum[node*2]+sum[node*2+1];
}
//区间修改 A[l,r] += c 
void updateSegment(int l,int r,int c,int x,int y,int node) {
	if(l<=x && y<=r) {
		sum[node] += (ll)c*(y-x+1);
		add[node] += c;
		return ;
	}
	pushDown(node,y-x+1);
	int mid = (x+y)/2;
	if(l<= mid) updateSegment(l,r,c,x,mid,node*2);
	if(r > mid) updateSegment(l,r,c,mid+1,y,node*2+1);
	sum[node] = sum[node*2]+sum[node*2+1]; 
}

ll query(int l,int r,int x,int y,int node) {
	if(l<=x && y<=r) return sum[node];
	pushDown(node,y-x+1);
	int mid = (x+y)/2;
	ll ans = 0;
	if(l<=mid) ans += query(l,r,x,mid,node*2);
	if(r>mid) ans += query(l,r,mid+1,y,node*2+1);
	return ans;
} 
int main() {
	cin>>n>>m;
	for(int i=1; i<=n; i++) cin>>A[i];
	build(1,n,1);
	while(m--) {
		cin>>ch;
		if(ch=='Q') {
			cin>>a>>b;
			cout<<query(a,b,1,n,1)<<endl;
		} else {
			cin>>a>>b>>c;
			updateSegment(a,b,c,1,n,1);
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值