线段树板子求助!
  • 板块灌水区
  • 楼主我是歌者
  • 当前回复4
  • 已保存回复4
  • 发布时间2024/10/5 09:46
  • 上次更新2024/10/5 11:32:51
查看原帖
线段树板子求助!
566190
我是歌者楼主2024/10/5 09:46
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct node{
	int l,r,w,add;
}tree[500100];
int arr[10010];
void build(int l,int r,int idx){
	tree[idx].l=l;
	tree[idx].r=r;
	if(l==r){
		tree[idx].w=arr[l];
		return;
	}
	build(l,(l+r)/2,idx*2);
	build((l+r)/2,r,idx*2+1);
	tree[idx].w=tree[idx*2].w+tree[idx*2+1].w;
	return;	
}
void spread(int idx){
	if(tree[idx].add!=0){
		tree[idx*2].w+=tree[idx].add*(tree[idx*2].r-tree[idx*2].l+1);
		tree[idx*2+1].w+=tree[idx].add*(tree[idx*2+1].r-tree[idx*2+1].l+1);
		tree[idx*2].add+=tree[idx].add;
		tree[idx*2+1].add+=tree[idx].add;
		tree[idx].add=0;
	}
	return;
}
void add(int l,int r,int w,int idx){
	if(tree[idx].l>=l&&tree[idx].r<=r){
		tree[idx].w+=w*(tree[idx].r-tree[idx].l+1);
		tree[idx].add+=w;
		return;
	}
	spread(idx);
	int mid=(l+r)/2;
	if(mid<r){
		add(l,r,w,idx*2+1);
	}
	if(mid>=l){
		add(l,r,w,idx*2);
	}
	tree[idx].w=tree[idx*2].w+tree[idx*2+1].w;
}
long long int check(int l,int r,int idx){
	if(tree[idx].l>=l&&tree[idx].r<=r){
		return tree[idx].w;
	}
	spread(idx);
	if(tree[idx].r<l||tree[idx].l>r) return 0;
	int mid=(tree[idx].l+tree[idx].r)/2;
	long long int ans=0;
	if(l<=mid) ans+=check(l,r,idx*2);
	if(r>mid) ans+=check(l,r,idx*2+1);
	return ans;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>arr[i];
	}
	build(1,n,1);
	while(m--){
		int a=0;
		cin>>a;
		if(a==1){
			int x=0,y=0,k=0;
			cin>>x>>y>>k;
			add(x,y,k,1);
		}
		else{
			int x=0,y=0;
			cin>>x>>y;
			cout<<check(x,y,1);
		}
	}
	return 0;
}

题面在P3372 没法输入。

2024/10/5 09:46
加载中...