• 【模板】线段树(区间加)


    代码复杂度较高的数据结构……写过的最长的模板(你才写过几个模板啊)

    这么个东西:

    线段树是棵平衡二叉树qwq 所以我们可以用(i*2)(i*2+1)分别表示(i)的左儿子和右儿子

    有点类似分块的思想 or 树状数组……???也是拆分拆分拆分求和求和求和

    设置add的标记,省去一个个节点修改的很多时间

    在修改&查询中不断维护父子关系

    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #define ll long long
    #define MAXN 1000001
    #define leftson cur<<1
    #define rightson cur<<1|1 
    #define mid ((l+r)>>1)
    #define push_up ans[cur]=ans[leftson]+ans[rightson]
    #define push_down lazyadd(leftson,l,mid,tag[cur]); lazyadd(rightson,mid+1,r,tag[cur]); tag[cur]=0
    using namespace std;
    ll ans[MAXN<<2],tag[MAXN<<2];
    void build(ll cur,ll l,ll r)
    {
        if (l==r)
        {
            scanf("%lld",&ans[cur]);
            return;
        }
        build(leftson,l,mid);
        build(rightson,mid+1,r);
        push_up;
    }
    inline void lazyadd(ll cur,ll l,ll r,ll delta)
    {
        tag[cur]+=delta;
        ans[cur]+=delta*(r-l+1);
    }
    inline void change(ll adl,ll adr,ll cur,ll l,ll r,ll delta)
    {
        if (adl<=l&&r<=adr)
        {
            ans[cur]+=delta*(r-l+1);
            tag[cur]+=delta;
            return;
        }
        push_down;
        if (adl<=mid) change(adl,adr,leftson,l,mid,delta);
        if (adr>mid)  change(adl,adr,rightson,mid+1,r,delta);
        push_up;
    }
    long long query(ll quel,ll quer,ll cur,ll l,ll r)
    {
        if (quel<=l&&r<=quer)
        {
            return ans[cur];
        }
        push_down;
        ll answer=0;
        if (quel<=mid)
        {
            answer+=query(quel,quer,leftson,l,mid);
        }
        if (quer>mid)
        {
            answer+=query(quel,quer,rightson,mid+1,r);
        }
        return answer;
    }
    int main()
    {
        ll n,m;
        scanf("%lld%lld",&n,&m);
        int cs;
        build(1,1,n);
        ll a,b,c;
        for (ll i=1;i<=m;i++)
        {
            scanf("%d",&cs);
            if (cs==1)
            {
                scanf("%lld%lld%lld",&a,&b,&c);
                change(a,b,1,1,n,c);
                continue;
            }
            scanf("%lld%lld",&a,&b);
            printf("%lld
    ",query(a,b,1,1,n));
        }
        return 0;
    }
    
  • 相关阅读:
    STM32标准库_05 | 用定时器写通用串口接收
    STM32标准库_04 | 串口接收不定长数据
    STM32标准库_03 | 串口printf打印
    STM32标准库_02 | 从按键开始认识状态机编程
    STM32标准库_01 | 搭建自己的程序框架
    STM32CubeMX的使用
    阿里云购买云服务器与域名
    阿里云物联网平台接入(使用MQTT协议)
    JAVA的JDK和API的区别是什么?
    Java经典实例
  • 原文地址:https://www.cnblogs.com/Kan-kiz/p/10620906.html
Copyright © 2020-2023  润新知