POJ - 3468 A Simple Problem with Integers

I just started to learn the line segment tree, take this question as an example again, and make some notes

Question meaning: The question has two operations, one is to ask the sum of the [l,r] interval, and the other is to add C to each digit in the [l,r] interval

Analysis: Obviously, it is time-consuming and inefficient to directly add the number C to each digit in the interval, so we have to find another way, which is the lazy operation.

  The lazy operation means that we do not add C to the numbers in the [l,r] interval first, that is, we do not directly add C to each number of the root of the tree, but push the mark +C to its two children. On the node, and update the child node sum[rt<<1]+=(tree[rt<<1].r-tree[rt<<1].l+1)*C (same for the right node), add [rt<<1]+=add[rt], add[rt]=0; in this way, only when this interval is used, will it use the sub-interval of this interval to update its own interval sum, Greatly improved efficiency

//pushdown
void pushdown(int rt){
	if(add[rt]){
		add[rt<<1]+=add[rt];
		add[rt<<1|1]+=add[rt];
		sum[rt<<1]+=1LL*(tree[rt<<1].r-tree[rt<<1].l+1)*add[rt];
		sum[rt<<1|1]+=1LL*(tree[rt<<1|1].r-tree[rt<<1|1].l+1)*add[rt];
		add[rt]=0;
	}
}

  Because of the lazy operation, the node information will only be updated when this node is used. Therefore, when querying, the pushdown function must be used to push down the mark.

  Below is the personal code

#define debug
#include<stdio.h>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<functional>
#include<iomanip>
#include<map>
#include<set>
#define pb push_back
#define dbg(x) cout<<#x<<" = "<<(x)<<endl;
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll>PLL;
typedef pair<int,ll>Pil;
const ll INF = 0x3f3f3f3f;
const double inf=1e8+100;
const double eps=1e-8;
const int maxn =1e6;
const int N = 510;
const ll mod=1e9+7;
//------
//define
struct node{
	int l, r;
}tree[maxn<<2];
ll sum[maxn<<2],add[maxn<<2];
//pushup
void pushup(int rt) {
	sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
//pushdown
void pushdown(int rt){
	if(add[rt]){
		add[rt<<1]+=add[rt];
		add[rt<<1|1]+=add[rt];
		sum[rt<<1]+=1LL*(tree[rt<<1].r-tree[rt<<1].l+1)*add[rt];
		sum[rt<<1|1]+=1LL*(tree[rt<<1|1].r-tree[rt<<1|1].l+1)*add[rt];
		add[rt]=0;
	}
}
//buildtree
void build(int l,int r,int rt) {
	tree[rt].l=l;
	tree[rt].r=r;
	add[rt]=0;
	if(l==r) {
		//gra[rt]=a[l];
		scanf("%lld",&sum[rt]);
		return;
	}
	int m=l+r>>1;
	build(l,m,rt<<1);
	build(m+1,r,rt<<1|1);
	pushup(rt);
}
//update
void update(int L,int R,int C,int rt){
	if(tree[rt].l==L&&tree[rt].r==R){
		add[rt]+=C;
		sum[rt]+=1ll*C*(R-L+1);
		return;
	}
	if(tree[rt].l==tree[rt].r)return;
	pushdown(rt);
	int m=tree[rt].l+tree[rt].r>>1;
	if(R<=m){
		update(L,R,C,rt<<1);
	}else if(L>m){
		update(L,R,C,rt<<1|1);
	}else{
		update(L,m,C,rt<<1);
		update(m+1,R,C,rt<<1|1);
	}
	pushup(rt);
}
//query
ll query(int L,int R,int rt) {
	if(L==tree[rt].l&&R==tree[rt].r){
		return sum[rt];
	}
	pushdown(rt);
	ll ans=0;
	int m=tree[rt].l+tree[rt].r>>1;
	if(R<=m){
		ans+=query(L,R,rt<<1);
	}else if(L>m){
		ans+=query(L,R,rt<<1|1);
	}else{
		ans+=query(L,m,rt<<1);
		ans+=query(m+1,R,rt<<1|1);
	}
	return ans;
}
//solve
void solve() {
	int n,t;
	while(~scanf("%d%d",&n,&t)){
		build(1,n,1);
		while(t--){
			char mark[2];
			int A,B,C;
			scanf("%s",&mark);
			if(mark[0]=='Q'){
				scanf("%d%d",&A,&B);
				printf("%lld\n",query(A,B,1));
			}else{
				scanf("%d%d%d",&A,&B,&C);
				update(A,B,C,1);
			}
		}
	}
}
//main
int main() {
//	ios_base::sync_with_stdio(false);
#ifdef debug
	freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
// cin.tie(0);
// cout.tie(0);
	solve();
	/*
		#ifdef debug
			fclose(stdin);
			fclose(stdout);
			system("out.txt");
		#endif
	*/
	return 0;
}

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324986215&siteId=291194637