警示后人(9pts可以看下)
查看原帖
警示后人(9pts可以看下)
800499
suzhikz楼主2023/8/17 14:37

1.判断越界。 2.看代码注释

#include<iostream>
#define int long long
using namespace std;
const int N=100005;
int n,m;
int a[N];
int sum[N<<2],tag[N<<2];
int ls(int x){
	return x<<1;
}
int rs(int x){
	return x<<1|1;
}
void push_up(int x){
	sum[x]=sum[ls(x)]+sum[rs(x)];
}
void build(int x,int l,int r){
	if(l==r){
		sum[x]=a[l];
		return;
	}
	int mid=(l+r)/2;
	build(ls(x),l,mid);
	build(rs(x),mid+1,r);
	push_up(x);
}
void f(int x,int l,int r){
	int mid=(l+r)/2;
	tag[ls(x)]+=tag[x];
	tag[rs(x)]+=tag[x];
	sum[ls(x)]+=(mid-l+1)*tag[x];
	sum[rs(x)]+=(r-mid)*tag[x];
	tag[x]=0;
}
void change(int nl,int nr,int k,int x,int l,int r){
	if(nl<=l&&nr>=r){
		tag[x]+=k;
		sum[x]+=(r-l+1)*k;
		return;
	}
	f(x,l,r);
	int mid=(l+r)/2;
	if(nl<=mid){
		change(nl,nr,k,ls(x),l,mid);
	}
	if(nr>mid)change(nl,nr,k,rs(x),mid+1,r);
	push_up(x);
	return;
}
int query(int x,int l,int r,int nl,int nr){
	if(nl<=l&&nr>=r)return sum[x];
	int res=0;
	f(x,l,r);
	int mid=(l+r)/2;
	if(nl<=mid)res+=query(ls(x),l,mid,nl,nr);
	if(nr>mid)res+=query(rs(x),mid+1,r,nl,nr);
	return res;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=n;i>1;i--){
		a[i]-=a[i-1];
	}
	build(1,1,n);
	while(m--){
		int a;
		cin>>a;
		if(a==1){
			int l,r,k,d;
			cin>>l>>r>>k>>d;
			change(l,l,k,1,1,n);
			if(l<r)change(l+1,r,d,1,1,n);
			if(r<n)change(r+1,r+1,-k-(r-l)*d,1,1,n);//在差分序列最后一项应加上-k-(r-l)*d,而不是-k-(r-l+1)*d,
		}else{
			int p;
			cin>>p;
			cout<<query(1,1,n,1,p)<<endl;
		}
	}
	return 0;
}

2023/8/17 14:37
加载中...