线段树求助
  • 板块灌水区
  • 楼主North_encounter
  • 当前回复4
  • 已保存回复4
  • 发布时间2023/10/16 16:47
  • 上次更新2023/11/2 13:27:04
查看原帖
线段树求助
850632
North_encounter楼主2023/10/16 16:47

从一开始处理就停止工作,就是asks函数,

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[2*100001];
struct tree{
	int l,r;
	int pre,tag;
}t[4*1000001+4];
inline void build(int p,int l,int r){
	t[p].l=l;t[p].r=r;
	if(l==r){
		t[p].pre=a[l];
	}
	int mid=(l+r)>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	t[p].pre=t[2*p].pre+t[2*p+1].pre;
}
inline void pushtag(int p){
	if(t[p].tag!=0){
		t[2*p].pre+=t[p].tag*(t[p*2].r-t[p*2].l+1);
		t[2*p+1].pre+=t[p].tag*(t[p*2+1].r-t[p*2+1].l+1);
		t[2*p].tag+=t[p].tag;
		t[2*p+1].tag+=t[p].tag;
		t[p].tag=0;
	}
}
inline void change(int p,int l,int r,int k){
	if(l<=t[p].l&&r>=t[p].r){
		t[p].pre+=k*(t[p].r-t[p].l+1);
		t[p].tag+=k;
	}
	pushtag(p);
	int mid=(t[p].l+t[p].r)>>1;
	if(l<=mid) change(p*2,l,r,k);
    if(r>mid) change(p*2+1,l,r,k);
    t[p].pre=t[p*2].pre+t[p*2+1].pre;
}
inline int asks(int p,int x,int y){
	if(x<=t[p].l&&y>=t[p].r) return t[p].pre;
	pushtag(p);
	int mid=(t[p].l+t[p].r)>>1;
	int ans=0;
	if(x<=mid){
		ans+=asks(2*p,x,y);
	}
	if(x>mid){
		ans+=asks(2*p+1,x,y);
	}
	return ans;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	int op=0;
	int x=0,y=0,k=0;
	for(int i=1;i<=m;i++){
		scanf("%d",&op);
		switch(op){
			case 1:{
				scanf("%d%d%d",&x,&y,&k);
				change(1,x,y,k);
				break;
			}
			case 2:{
				scanf("%d%d",&x,&y);
				int qp=asks(1,x,y);
				cout<<qp<<endl;
				break;
			}
		}
	}
	return 0;
}

样例

5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4

输出

11
8
20
2023/10/16 16:47
加载中...