社区讨论

指针线段树 0pts 求条

P3372【模板】线段树 1参与者 2已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@m0259vex
此快照首次捕获于
2024/08/20 16:10
2 年前
此快照最后确认于
2024/08/20 18:00
2 年前
查看原帖
CPP
#include <cstdio>
typedef long long ll;
struct node {
	ll tag,ans;
	node* l;
	node* r;
	inline node(void) {
		tag=ans=0,l=r=NULL;
	} 
};
const int N = 1e5;
ll a[N+5],k;
int n,m,op,x,y;
inline void pushup(node* &p) {
	p->ans=p->l->ans+p->r->ans; 
}
inline void make(node* &p) {
	if(p->l==NULL)p->l=new node;
	if(p->r==NULL)p->r=new node;
}
inline void pushdown(node* &p,int s,int t,int mid) {
	if(p->tag) {
		make(p);
		p->l->ans += (mid-s+1)*p->tag,p->l->tag+=p->tag;
		p->r->ans += (t-mid)*p->tag,p->r->tag+=p->tag;
		p->tag=0;
	}
}
inline void build(node* &p,int l,int r) {
	if(l == r) {
		p->ans = a[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(p->l,l,mid),build(p->r,mid+1,r);
	pushup(p);
}
inline void update(node* &p,int s,int t,int l,int r,ll k) {
	if(l <= s && t <= r) {
		p->ans += (t-s+1) * k, p->tag += k;
		return ;
	}
	int mid=(s+t)>>1;
	pushdown(p,s,t,mid);
	if(l<=mid)update(p->l,s,mid,l,r,k);
	if(mid<r)update(p->r,mid+1,t,l,r,k);
	pushup(p); 
}
inline ll query(node* &p,int s,int t,int l,int r)
{
	if(l <= s && t <= r) {
		return p->ans;
	}
	int mid=(s+t)>>1;
	pushdown(p,s,t,mid);
	ll sum=0;
	if(l<=mid)sum=query(p->l,s,mid,l,r);
	if(mid<r)sum+=query(p->r,mid+1,t,l,r);
	return sum; 
}
int main(void) {
	node* p=new node; 
	scanf("%d%d", &n, &m);
	for(int i = 1;i <= n;++ i) {
		scanf("%lld", &a[i]);
	}
	build(p,1,n);
	while(m--) {
		scanf("%d",&op);
		switch(op) {
			case 1: scanf("%d%d%lld",&x,&y,&k),update(p,1,n,x,y,k);break;
			case 2: scanf("%d%d",&x,&y),printf("%lld\n",query(p,1,n,x,y));break;
		}
	}
	return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...