zoukankan      html  css  js  c++  java
  • 【数据结构】树状数组的几种用法

    用法:

    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这些关系啥的

    导致并不是太懂

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

  • 相关阅读:
    SpringAOP--动态数据源
    SpringAOP--代理
    SpringAOP--aop使用
    Kafka03--Kafka消费者使用方式
    Kafka02--Kafka生产者简要原理
    Kafka01--Kafka生产者使用方式
    SpringBoot中的日志使用:
    LCS&&LRC&&LIS问题
    解决Idea.exe无法启动问题(idea2017.3版本)
    七牛云简单实用-uploadManager.put(..)抛出异常
  • 原文地址:https://www.cnblogs.com/BrokenString/p/9278503.html
Copyright © 2011-2022 走看看