线段树模板

本文介绍了一种高效的数据结构——段式懒惰传播树,用于处理区间更新和查询问题。通过递归构建和更新树结构,实现对数组区间进行增减操作,并能快速查询区间和。该文详细解释了其工作原理、核心算法及具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<cstdio>
using namespace std;
int n,m;
long long aa[100005],tree[100005*4],lazy[100005*4];
void build(int l,int r,int fa)
{
    if(l==r)
    {
        tree[fa]=aa[l];
        return;
    }
    int m=(l+r)/2;
    build(l,m,fa*2);
    build(m+1,r,fa*2+1);
    tree[fa]=tree[fa*2]+tree[fa*2+1];
}
void pushdown(int l,int r,int fa)
{
    int m=(l+r)/2;
    lazy[fa*2]+=lazy[fa];
    lazy[fa*2+1]+=lazy[fa];
    tree[fa*2]+=(m-l+1)*lazy[fa];
    tree[fa*2+1]+=(r-m)*lazy[fa];
    lazy[fa]=0;
}
void update(int l,int r,int L,int R,int fa,int k)
{
    if(L<=l&&R>=r)
    {
        lazy[fa]+=k;
        tree[fa]+=(r-l+1)*k;
        return;
    }
    if(lazy[fa]!=0)
    pushdown(l,r,fa);
    int m=(l+r)/2;
    if(L<=m)
    update(l,m,L,R,fa*2,k);
    if(R>m)
    update(m+1,r,L,R,fa*2+1,k);
    tree[fa]=tree[fa*2]+tree[fa*2+1];
}
long long query(int l,int r,int L,int R,int fa)
{
    long long ans=0;
    if(L<=l&&R>=r)
    {
        return tree[fa];
    }
    if(lazy[fa]!=0)
    pushdown(l,r,fa);
    int m=(l+r)/2;
    if(L<=m)
    ans+=query(l,m,L,R,fa*2);
    if(R>m)
    ans+=query(m+1,r,L,R,fa*2+1);
    return ans;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&aa[i]);
    }    
    build(1,n,1);
    for(int i=1;i<=m;i++)
    {
        int x;
        scanf("%d",&x);
        if(x==2)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            long long sum=query(1,n,a,b,1);    
            printf("%lld\n",sum);
        }
        if(x==1)
        {
            int a1,b1,c1;
            scanf("%d%d%d",&a1,&b1,&c1);
            update(1,n,a1,b1,1,c1);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值