线段树样例能过 10pts 求调,玄关。
查看原帖
线段树样例能过 10pts 求调,玄关。
604906
Guizy楼主2023/9/10 17:05
#include<bits/stdc++.h>
#define int long long
using namespace std;

int a[400001],x,y,k,cnt;
int tree[400001],flag,flag2;
int lzy_tag[400001],n,m;

void build(int l,int r,int id){
	
	if(l==r){
		tree[id]=a[l];
		return ;
	}
	else{
		int mid=(l+r)>>1;
		build(l,mid,id*2);
		build(mid+1,r,id*2+1);
		tree[id]=tree[id*2]+tree[id*2+1];
		return ;
	}
	return ;
}

void push_lzyt(int id,int len){
	
	int k=lzy_tag[id];
	lzy_tag[id]=0;
	
	lzy_tag[id*2]+=k;
	lzy_tag[id*2+1]+=k;
	tree[id*2]+=k*(len-len/2);
	tree[id*2+1]+=k*(len/2);
}

void upd(int l,int r,int id){
	
	if(l==r&&l>=x&&r<=y){
		tree[id]+=k;
	}
	else{		
		if(l>y||r<x){
			return;
		} 
		if(l>=x&&r<=y){
			tree[id]+=k*(r-l+1);
			if(l!=r) lzy_tag[id]=k;
		}		
		else{
			int mid=(l+r)>>1;
			push_lzyt(id,r-l+1);
			upd(l,mid,id*2);
			upd(mid+1,r,id*2+1);	
			tree[id]=tree[id*2]+tree[id*2+1];		 
		}
	}	
}

int ask(int l,int r,int id){
	
	if(l>y||r<x){
		return 0;
	}	
	else if(l>=x&&r<=y){
		return tree[id];
	}
	else{
		push_lzyt(id,r-l+1);
		int mid=(l+r)>>1;
		return ask(l,mid,id*2)+ask(mid+1,r,id*2+1);
	}
}

signed main(){
	
	scanf("%d%d",&n,&m);
	
	for(int i=1;i<=n;i++){
		scanf("%d",a+i);
	}
	build(1,n,1);
	while(m--){
		scanf("%d%d%d",&flag,&x,&y);
		if(flag==1){
			scanf("%d",&k);
			upd(1,n,1);
		}
		else{
			flag2=0;
			printf("%d\n",ask(1,n,1));
		}
	}
	
	return 0;
}
2023/9/10 17:05
加载中...