本蒟蒻刚学线段树,不知为何TLE三个点
查看原帖
本蒟蒻刚学线段树,不知为何TLE三个点
181400
Henry_Wu楼主2021/2/5 16:39

代码见下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#define ll long long
using namespace std;
ll n,m,a[200010];
struct tree{
	ll l,r,num,lazy;
}t[500010];
inline int read()
{
	register int ret=0,c=getchar(),b=1;
	while(!isdigit(c))b=c=='-'?-1:1,c=getchar();
	while(isdigit(c))ret=ret*10+c-'0',c=getchar();
	return ret*b;
}
void build(int p,int l,int r){
	t[p].l=l;
	t[p].r=r;
	if(l==r){
		t[p].num=a[l];
		return ;
	}
	ll mid=(l+r)>>1;
	build(2*p,l,mid);
	build(2*p+1,mid+1,r);
	t[p].num=t[2*p].num+t[2*p+1].num;
	return ;
}
void pushdown(int p,int l,int r){
    if(t[p].lazy){
		int mid=(l+r)>>1;
        t[2*p].num+=t[p].lazy*(mid-l+1);
        t[2*p+1].num+=t[p].lazy*(r-mid);
        t[2*p].lazy+=t[p].lazy;
        t[2*p+1].lazy+=t[p].lazy;
        t[p].lazy=0;
    }
}
void change(int p,int l,int r,int x,int y,int k){
	if(l==r){
		t[p].num+=k;
		return ;
	}
	pushdown(p,l,r);
	ll mid=(l+r)>>1;
	if(mid>=x) change(2*p,l,mid,x,y,k);
	if(y>mid) change(2*p+1,mid+1,r,x,y,k);
	t[p].num=t[2*p].num+t[2*p+1].num;
}
ll query(int p,int l,int r,int x,int y){
	
	if(x<=l&&y>=r){
		return t[p].num;
	}
	ll mid=(l+r)>>1,t1=0,t2=0; 
	if(x<=mid) t1=query(2*p,l,mid,x,y);
	if(y>mid) t2=query(2*p+1,mid+1,r,x,y);
	return t1+t2;
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++) a[i]=read();
	build(1,1,n);
	
	while(m--){
		int p;
		p=read();
		if(p==1){
			ll x,y,k;
			x=read(),y=read(),k=read();
			change(1,1,n,x,y,k); 
		}
		else{
			ll l,r;
			l=read(),r=read();
			ll ans=query(1,1,n,l,r);
			printf("%d\n",ans);
		}
	}
} 
2021/2/5 16:39
加载中...