初学线段树 0pts求调(玄关)
查看原帖
初学线段树 0pts求调(玄关)
778975
QAQ_YTH楼主2024/4/18 23:04

rt,能过样例,代码如下:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5;
struct data{
	int l,r,sum,add;
}tr[N<<2];
int n,m,a[N],op,x,y,k;
inline int read(){
	int flag=1,res=0;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		flag=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		res=res*10+ch-'0';
		ch=getchar();
	}
	return res*flag;
}
void pushup(int k){
	tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
void pushdown(int k){
	tr[k<<1].add+=tr[k].add;
	tr[k<<1|1].add+=tr[k].add;
	tr[k<<1].sum+=tr[k].add*(tr[k<<1].r-tr[k<<1].l+1);
	tr[k<<1|1].sum+=tr[k].add*(tr[k<<1|1].r-tr[k<<1|1].l+1);
	tr[k].add=0;
}
void build(int k,int l,int r){
	tr[k].l=l,tr[k].r=r,tr[k].add=0;
	if(l==r){tr[k].sum=a[l];return;}
	int mid=l+r>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	tr[k].add=tr[k<<1].add+tr[k<<1|1].add;
}
void add(int k,int l,int r,int x){
	if(tr[k].r==0||tr[k].l==0)return;
	if(l<=tr[k].l&&tr[k].r<=r){
		tr[k].add+=x;
        tr[k].sum+=x*(tr[k].r-tr[k].l+1);
		return;
	}
	int mid=(tr[k].l+tr[k].r)>>1;
	pushdown(k);
	if(l<=mid)add(k<<1,l,r,x);
	if(r>mid)add(k<<1|1,l,r,x);
	pushup(k);
	return;
}
int query(int k,int l,int r,int ll,int rr){
	if(tr[k].r<l||tr[k].l>r)return 0;
	if(tr[k].l>=l&&tr[k].r<=r){
		return tr[k].sum;
	}
	int mid=ll+rr>>1,ans=0;
	pushdown(k);
	if(mid>=l)ans+=query(k<<1,l,r,ll,mid);
	if(mid<r)ans+=query(k<<1|1,l,r,mid+1,rr);
	return ans;
}
signed main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++){
		a[i]=read();
	}
	build(1,1,n);
	while(m--){
		op=read();
		if(op==1){
			x=read(),y=read(),k=read();
			add(1,x,y,k);
		}else{
			x=read(),y=read();
			cout<<query(1,x,y,1,n)<<endl;
		}
	}
	return 0;
}
2024/4/18 23:04
加载中...