20pts 线段树求助
查看原帖
20pts 线段树求助
537627
_LSA_楼主2022/4/2 16:31
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAX = 1e5+10;
long long read(){
	long long f=1,r=0;
	char ch;
	do ch=getchar(); while(!isdigit(ch) && ch!='-');
	if(ch=='-') f=-1,ch=getchar();
	do r=r*10+ch-48,ch=getchar(); while(isdigit(ch));
	return r*f;
}
void write(long long X){
	if(X < 0) putchar('-'),X=-X;
    if(X>9) write(X/10); 
    putchar(X%10+'0'); 
}
long long n,m;
long long a[MAX],sum[MAX<<5],tag[MAX<<5];
inline void Push_up(int rt){sum[rt] = sum[rt<<1]+sum[rt<<1|1];}
void Build(int l,int r,int rt){
	if(l == r){
		sum[rt] = a[l];
		return;
	}
	int mid = (l+r)>>1;
	Build(l,mid,rt<<1);
	Build(mid+1,r,rt<<1|1);
	Push_up(rt);
}
inline void Push_down(int rt,int l,int r){
	if(!tag[rt]) return;
	int mid = (l+r)>>1;
	tag[rt<<1] = tag[rt];
	tag[rt<<1|1] = tag[rt];
	sum[rt<<1] += (mid-l+1)*tag[rt];
	sum[rt<<1|1] += (r-mid)*tag[rt];
	tag[rt] = 0;
}
void Update(int nl,int nr,int c,int l,int r,int rt){
	if(l >= nl && r <= nr){
		sum[rt] += c*(r-l+1);
		tag[rt] += c;
		return;
	}
	int mid = (l+r)>>1;
	Push_down(rt,l,r);
	if(mid >= nl) Update(nl,nr,c,l,mid,rt<<1);
	if(mid < nr) Update(nl,nr,c,mid+1,r,rt<<1|1);
	Push_up(rt);
}
long long Query(int nl,int nr,int l,int r,int rt){
	if(l >= nl && r <= nr) return sum[rt];
	Push_down(rt,l,r);
	int mid = (l+r)>>1;
	int ans = 0;
	if(mid >= nl) ans += Query(nl,nr,l,mid,rt<<1);
	if(mid < nr) ans += Query(nl,nr,mid+1,r,rt<<1|1);
	return ans;
}
int main(){
	n = read(); m = read();
	for(int i=1;i<=n;i++)
		a[i] = read();
	Build(1,n,1);
	while(m--){
		int op = read();
		if(op == 1){
			int x = read(),y = read(),k = read();
			Update(x,y,k,1,n,1);
		}
		else{
			int x = read(),y = read();
			write(Query(x,y,1,n,1));
			puts("");
		}
	}
	return 0;
}
2022/4/2 16:31
加载中...