求助&关于做题时间的疑问
查看原帖
求助&关于做题时间的疑问
121813
老子是北瓜楼主2020/9/13 17:22

真的不知道哪里错了…… 你们调线段树要花多长时间

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
long long a[100005];
long long sum[400005],add[400005];
int n,m;
void build(int rt,int l,int r){
	if(l==r){
		sum[rt]=a[l];
		return ;
	}
	int mid=(l+r)>>1;
	int lc=rt<<1,rc=(rt<<1)+1;
	build(lc,l,mid);
	build(rc,mid+1,r);
	sum[rt]=sum[lc]+sum[rc]; 
} 
void change(int rt,int l,int r,int ql,int qr,int k){
	if(l==ql && r==qr){
		sum[rt]+=(r-l+1)*k;
		add[rt]+=k;
		return ;
	}
	int mid=(l+r)>>1,tmp;
	int lc=rt<<1,rc=(rt<<1)+1;
	if(ql<=mid){
		if(qr<mid) tmp=qr;
		else tmp=mid;
		change(lc,l,mid,ql,tmp,k);
	}
	if(qr>mid){
		if(ql>mid+1) tmp=ql;
		else tmp=mid+1;
		change(rc,mid+1,r,tmp,qr,k);
	}
	sum[rt]=sum[lc]+sum[rc];
}
long long query(int rt,int l,int r,int ql,int qr){
	if(l==ql && r==qr)
		return sum[rt];
	int mid=(l+r)>>1,tmp;
	int lc=rt<<1,rc=(rt<<1)+1;
	if(add[rt]!=0){
		sum[lc]=sum[lc]+(mid-l+1)*add[rt];
		sum[rc]=sum[rc]+(r-mid)*add[rt];
		add[lc]=add[lc]+add[rt];
		add[rc]=add[rc]+add[rt];
		add[rt]=0;
	}
	int ans=0;
	if(ql<=mid){
		if(qr<mid) tmp=qr;
		else tmp=mid;
		ans+=query(lc,l,mid,ql,tmp);
	}
	if(qr>mid){
		if(ql>mid+1) tmp=ql;
		else tmp=mid+1;
		ans+=query(rc,mid+1,r,tmp,qr);
	}
	return ans;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; ++i)
		scanf("%lld",&a[i]);
	build(1,1,n);
	int ql,qr,k;
    long long num;
	for(int i=1; i<=m; ++i)
	{
		scanf("%d",&k);
		if(k==1){
			scanf("%d%d%lld",&ql,&qr,&num);
			change(1,1,n,ql,qr,num);
		}
		else
		{
			scanf("%d%d",&ql,&qr);
			cout<<query(1,1,n,ql,qr)<<endl;
		}
	}
	return 0;
}
2020/9/13 17:22
加载中...