社区讨论

萌新刚学OI 求调悬关

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

讨论操作

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

当前回复
13 条
当前快照
1 份
快照标识符
@lz95u6dn
此快照首次捕获于
2024/07/31 09:20
2 年前
此快照最后确认于
2024/07/31 10:57
2 年前
查看原帖
RT
CPP
#include<bits/stdc++.h>
using namespace std;
struct node{
	int left,right;
	int value,lazy=0;
}tree[4000005];
int a[1000005];
void build(int l,int r,int root){
	tree[root].left=l,tree[root].right=r;
	if(tree[root].left==tree[root].right){
		tree[root].value=a[l];
		return;
	}
	int mid=(tree[root].left+tree[root].right)/2;
	build(l,mid,tree[root].left);
	build(mid+1,r,tree[root].right);
	tree[root].value=tree[root*2].value+tree[root*2+1].value;
}
void spread(int root){
	if(tree[root].left==tree[root].right){
		return;
	}
	int lazy=tree[root].lazy;
	tree[root*2].lazy+=lazy;
	tree[root*2+1].lazy+=lazy;
	tree[root*2].value+=lazy*(tree[root*2].right-tree[root*2].left+1);
	tree[root*2+1].value+=lazy*(tree[root*2+1].right-tree[root*2].left+1);
	tree[root].lazy=0;
}
void update(int root,int l,int r,int v){
	if(tree[root].left>=l&&tree[root].right<=r){
		tree[root].lazy=v;
		tree[root].value+=(tree[root].right-tree[root].left+1);
		return;
	}
	spread(root);
	int mid=(tree[root].left+tree[root].right)/2;
	if(l<=mid) update(root*2,l,r,v);
	if(r>mid) update(root*2+1,l,r,v);
	tree[root].value=tree[root*2].value+tree[root*2+1].value;
}
long long query(int root,int l,int r){
	long long ans=0;
	if(tree[root].left>=l&&tree[root].right<=r){
		return tree[root].value;
	}
	spread(root);
	int mid=(tree[root].left+tree[root].right)/2;
	if(l<=mid) ans+=query(root*2,l,r);
	if(r>mid) ans+=query(root*2+1,l,r);
	return ans;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n,q;
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	build(1,n,1) ;
	while(q--){
		int op;
		cin>>op;
		if(op==1){
			int l,r,v;
			cin>>l>>r>>v;
			update(1,l,r,v);
		}else if(op==2){
			int l,r;
			cin>>l>>r;
			cout<<query(1,l,r)<<"\n";
		}
	}
	return 0;
}

回复

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

正在加载回复...