• 【数据结构】树状数组的几种用法


    用法:

    1. 单点修改
    2. 区间修改
    3. 单点查询
    4. 区间查询

    模板题:

    洛谷P3374:

    https://www.luogu.org/problemnew/show/P3374

    洛谷P3368:

    https://www.luogu.org/problemnew/show/P3368

    代码:

    洛谷P3374:

    #include<iostream>
    using namespace std;
    int n,m;
    int tree[2000010];
    int lowbit(int k)
    {
        return k & -k;//补码原则 
    }
    void add(int x,int k)
    {
        while(x<=n)
        {
            tree[x]+=k;
            x+=lowbit(x);//根据二进制原理加上本身的lowbit等于下一个值 
        }
    }
    int sum(int x)
    {
        int ans=0;
        while(x!=0)
        {
            ans+=tree[x];
            x-=lowbit(x);
        }
        return ans; 
    }
    int main()
    {
        std::ios::sync_with_stdio(false);//取消cincout的时间
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            int x;
            cin>>x;
            add(i,x);
        }
        for(int i=1;i<=m;i++)
        {
            int a,b,c;
            cin>>a>>b>>c;
            if(a==1)
            add(b,c);//在b的位置加上c 
            if(a==2)
            cout<<sum(c)-sum(b-1)<<endl;//前缀和相减 
        }
    } 
    View Code

    洛谷P3368:

    #include<iostream>
    using namespace std;
    int n,m;
    int tree[500010];
    int num[500010];
    int lowbit(int k)
    {
        return k & -k;//补码原则 
    }
    void add(int x,int k)
    {
        while(x<=n)
        {
            tree[x]+=k;
            x+=lowbit(x);//根据二进制原理加上本身的lowbit等于下一个值 
        }
    }
    int sum(int x)
    {
        int ans=0;
        while(x!=0)
        {
            ans+=tree[x];
            x-=lowbit(x);
        }
        return ans; 
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        cin>>num[i];
        for(int i=1;i<=m;i++)
        {
            int a;
            cin>>a;
            if(a==1)
            {
                int x,y,z;
                cin>>x>>y>>z;
                add(x,z);
                add(y+1,-z);//把前面加上的多余减掉 
            }
            if(a==2)
            {
                int x;
                cin>>x;
                cout<<num[x]+sum(x)<<endl;//把原来的数加上后来加的 
            } 
        }
    } 
    View Code

    后记:

    原来就上过一遍这个了

    但是当时没有弄懂二进制和lowbit这些关系啥的

    导致并不是太懂

    现在再上一遍到是水到渠成了

  • 相关阅读:
    EF CodeFirst下,当实体结构发生修改怎么更新数据库结构 【常用总结】
    基于 ASP.NET Core 的 EF Core 入门
    autofac 一个接口多个实现的情况
    C#中使用HttpClient来Post数据的内容HttpContent的各种格式
    # 使用HttpClient的post,get 封装
    C# 模拟提交带附件(input type=file)的表单
    C#使用HttpClient上传文件并附带其他参数
    2021年总结一下
    PhpStorm+Xdebug断点调试
    PHP数组排序
  • 原文地址:https://www.cnblogs.com/BrokenString/p/9278503.html
Copyright © 2020-2023  润新知