社区讨论

95,求条

P3372【模板】线段树 1参与者 2已保存回复 1

讨论操作

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

当前回复
1 条
当前快照
1 份
快照标识符
@mjk4vnik
此快照首次捕获于
2025/12/24 22:53
2 个月前
此快照最后确认于
2025/12/27 11:30
2 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define kn 1050000
typedef long long ll;
using namespace std;

ll n,m;
ll a[kn];

struct tree{
	ll data,add;
	int left,right;
}t[kn*4+5];

void build(const int p,int left ,int right){
	t[p].left=left;
	t[p].right=right;
	if(left==right){
		t[p].data=a[left];
		return;
	}
	else{
		int mid=(left+right)>>1;
		build(p*2,left,mid),build(p*2+1,mid+1,right);
		t[p].data=t[p*2].data+t[p*2+1].data;
	}
}

void spread(int p){
	if(t[p].add){
		t[p*2].data+=t[p].add*(t[p*2].right-t[p*2].left+1);
		t[p*2+1].data+=t[p].add*(t[p*2+1].right-t[p*2+1].left+1);
		t[p*2].add+=t[p].add;
		t[p*2+1].add+=t[p].add;
		t[p].add=0;
	}
}

void change(const int p, int left, int right, int x) {
    if (left <= t[p].left && right >= t[p].right) {
        t[p].data += (ll)x * (t[p].right - t[p].left + 1);
        t[p].add += x;
        return;
    } else {
        spread(p);
        int mid = (t[p].left + t[p].right) >> 1;
        if (left <= mid) change(p*2, left, right, x);
        if (right > mid) change(p*2+1, left, right, x);
        t[p].data = t[p*2].data + t[p*2+1].data;
    }
}

ll ask(const int p,int left,int right){
	if(left<=t[p].left && right>=t[p].right) return t[p].data;
	int mid=(t[p].left+t[p].right)>>1;
	spread(p);
	ll ans=0;
	if(left<=mid) ans+=ask(p*2,left,right);
	if(right>mid) ans+=ask(p*2+1,left,right);
	return ans;
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);	
	for(int i=0;i<m;i++)
	{
		int c,a,b;
		cin>>c>>a>>b;
		if(c==1){
			int k;
			cin>>k;
			change(1,a,b,k);
		}
		else cout<<ask(1,a,b)<<'\n';
	}
	return 0;
} 

回复

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

正在加载回复...