社区讨论
指针线段树 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 条回复,欢迎继续交流。
正在加载回复...