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

    导致并不是太懂

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

  • 相关阅读:
    《TCP/IP详解》之二:流式数据交互
    《TCP/IP详解》之一:连接建立、断开
    异步日志实现
    关于继承和组合的一点总结
    GitHub源代码管理基本操作 Mossad
    移动APP的开发需求分析 Mossad
    对理想团队模式构建的设想以及对软件流程的理解 Mossad
    C语言I博客作业06
    C语言I博客作业02
    C语言I博客作业03
  • 原文地址:https://www.cnblogs.com/BrokenString/p/9278503.html
Copyright © 2011-2022 走看看