POJ——3468(线段树区间修改模板题)Simple Problem with Integers

原题链接:http://poj.org/problem?id=3468

题意:给你一个编号从1到N的整数序列,会进行若干个区间修改和查询功能,请你输出每次查询后的结果。

解题思路:这是一道线段树区间修改的模板题,我们理解好题意照做即可,要注意范围,利用long long来存储。

AC代码:

#include<bits/stdc++.h>

#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll>  pll;
typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 1e5+5;//最大值。
//****************分割线,以上为自定义代码模板*****************//


struct node{
	int l,r;//左右端点。
	ll sum,lazy;//区间和和lazy标记。
}SegTree[maxn<<2];
void BuildTree(int rt,int l,int r){
	SegTree[rt].l=l;SegTree[rt].r=r;
	SegTree[rt].lazy=0;
	if(l==r){
		cin>>SegTree[rt].sum;
		return;
	}
	BuildTree(rt<<1,l,(l+r)>>1);
	BuildTree(rt<<1|1,((l+r)>>1)+1,r);
	SegTree[rt].sum=SegTree[rt<<1].sum+SegTree[rt<<1|1].sum;
}
void PushDown(int rt){
	if(SegTree[rt].lazy){
		SegTree[rt<<1].lazy+=SegTree[rt].lazy;
		SegTree[rt<<1|1].lazy+=SegTree[rt].lazy;
		SegTree[rt<<1].sum+=(SegTree[rt<<1].r-SegTree[rt<<1].l+1)*SegTree[rt].lazy;
		SegTree[rt<<1|1].sum+=(SegTree[rt<<1|1].r-SegTree[rt<<1|1].l+1)*SegTree[rt].lazy;
		SegTree[rt].lazy=0;
	}
}
void UpDate(int rt,int c,int l,int r){
	if(SegTree[rt].l==l&&SegTree[rt].r==r){
		SegTree[rt].sum+=(SegTree[rt].r-SegTree[rt].l+1)*c;
		SegTree[rt].lazy+=c;
		return;
	}
	PushDown(rt);
	int mid=(SegTree[rt].l+SegTree[rt].r)>>1;
	if(r<=mid){
		UpDate(rt<<1,c,l,r);//全部在左子树。
	}
	else if(l>mid){
		UpDate(rt<<1|1,c,l,r);//全部在右子树。
	}
	else{
		UpDate(rt<<1,c,l,mid);
		UpDate(rt<<1|1,c,mid+1,r);
	}
	SegTree[rt].sum=SegTree[rt<<1].sum+SegTree[rt<<1|1].sum;
}
ll QueryTree(int rt,int l,int r){
	if(SegTree[rt].l==l&&SegTree[rt].r==r){
		return SegTree[rt].sum;
	}
	PushDown(rt);
	int mid=(SegTree[rt].l+SegTree[rt].r)>>1;
	ll ans=0;
	if(r<=mid){
		ans+=QueryTree(rt<<1,l,r);//全部在左子树。
	}
	else if(l>mid){
		//全部在右子树。
		ans+=QueryTree(rt<<1|1,l,r);
	}
	else{
		ans+=QueryTree(rt<<1,l,mid);
		ans+=QueryTree(rt<<1|1,mid+1,r);
	}
	return ans;
}
int main(){
	//freopen("in.txt", "r", stdin);//提交的时候要注释掉
	IOS;
	int n,q;
	while(cin>>n>>q){
		BuildTree(1,1,n);
		string op;
		int a,b,c;
		while(q--){
			cin>>op;
			if(op=="Q"){
				cin>>a>>b;
				cout<<QueryTree(1,a,b)<<endl;
			}
			else{
				cin>>a>>b>>c;
				UpDate(1,c,a,b);
			}
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

unique_pursuit

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值