线段树0分求助
查看原帖
线段树0分求助
335552
Christophe_楼主2021/10/1 22:27
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const ll N=1e5+5;
ll n,m,tr[N<<2],A[N],mark[N<<2];
void Build(ll l,ll r,ll p) {
	if(l==r) tr[p]=A[l];
	else {
		ll mid=(l+r)/2,lc=2*p,rc=2*p+1;
		Build(l,mid,lc);
		Build(mid+1,r,rc);
		tr[p]=tr[lc]+tr[rc];
	}
}
void Add(ll l,ll r,ll k,ll cl,ll cr,ll p) {
	if(cr<l||cl>r) return;
	else {
		if(cl>=l&&cr<=r) {
			tr[p]+=k*(cl-cr+1);
			if(cl!=cr) mark[p]+=k;
		} else {
			ll lc=2*p,rc=2*p+1,mid=(cl+cr)/2;
			tr[lc]+=mark[p]*(mid-cl+1);
			tr[rc]+=mark[p]*(cr-mid);
			mark[lc]+=mark[p];
			mark[rc]+=mark[p];
			mark[p]=0;
			Add(l,r,k,cl,mid,lc);
			Add(l,r,k,mid+1,cr,rc);
			tr[p]=tr[lc]+tr[rc];
		}
	}
}
ll Find(ll l,ll r,ll cl,ll cr,ll p) {
	if(cr<l||cl>r) return 0;
	else {
		if(cl>=l&&cr<=r) return tr[p];
		else {
			ll lc=2*p,rc=2*p+1,mid=(cl+cr)/2;
			tr[lc]+=mark[p]*(mid-cl+1);
			tr[rc]+=mark[p]*(cr-mid);
			mark[lc]+=mark[p];
			mark[rc]+=mark[p];
			mark[p]=0;
			return Find(l,r,cl,mid,lc)+Find(l,r,mid+1,cr,rc);
		}
	}
}
int main() {
	scanf("%lld%lld",&n,&m);
	for(ll i=1; i<=n; ++i) scanf("%lld",&A[i]);
	Build(1,n,1);
	for(ll i=1; i<=m; ++i) {
		ll t,x,y,k;
		scanf("%lld",&t);
		if(t==1) {
			scanf("%lld%lld%lld",&x,&y,&k);
			Add(x,y,k,1,n,1);
		} else {
			scanf("%lld%lld",&x,&y);
			ll ans=Find(x,y,1,n,1);
			printf("%lld\n",ans);
		}
	}
	return 0;
}

跟着知乎用户 @ Pecco 的线段树模板打的,已过样例和手造数据,但哪里错了呢?

2021/10/1 22:27
加载中...