• 树状数组


    每个节点  tree[i]=a[i-2^k+1]+....+a[i]

    k为取最低位的1;

    转变为二进制 

      例如 7:    tree 0111 = a 0111 

         8:    tree 1000 = a 0001 + a 0010 + a 0011 +...+ a 1000;

    取最低位的1

    int lowbit(int x)
    {
        return x&(-x);
    }

    修改:

    void add(int x,int k)
    {
        while(x<=n)
        {
            tree[x]+=k;
            x+=lowbit(x);
        }
    }/**

      7(111)          ans+=C[7]

    
    

    lowbit(7)=001  7-lowbit(7)=6(110)    ans+=C[6]

    
    

    lowbit(6)=010  6-lowbit(6)=4(100)    ans+=C[4]

    
    

    lowbit(4)=100  4-lowbit(4)=0(000)    



    *//

    查询(区间查询类似前缀和):

    int query(int x)
    {
        int ans=0;
        while(x>0)
        {
            ans+=tree[x];
            x-=lowbit(x);
        }
        return ans;
    }

    差分:

    对于 a 1 5 6 2 4  5 

    a[i]-a[i-1] 得到 b 1 4 1 -4 2 1

    可得 a[i]=b[1]+...+b[i];

    此时a 2-4 全部加上 2 

    a 1 7 8 4 4 5

    b 1 6 1 -4  0 5

    只有2 4 对应的只改变 2 +k 4 -k;

    只需要对应修改 2 4 的值

    洛谷3368:

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn=5e5+10;
    
    #define ll long long
    
    int tree[maxn];
    
    int lowbit(int x)
    {
        return x&(-x);
    }
    
    int n,m;
    
    void add(int x,int k)
    {
        while(x<=n)
        {
            tree[x]+=k;
            x+=lowbit(x);
        }
    }
    
    
    int query(int x)
    {
        int ans=0;
        while(x>0)
        {
            ans+=tree[x];
            x-=lowbit(x);
        }
        return ans;
    }
    
    signed main()
    {
        int a,b;
        scanf("%d%d%d",&n,&m,&b);
        add(1,b);
        for(int i=2;i<=n;i++)
        {
            scanf("%d",&a);
            add(i,a-b);
            b=a;
        }
        for(int i=1;i<=m;i++)
        {
            int cmd,x,y,pos;
            scanf("%d",&cmd);
            if(cmd==1)
            {
                scanf("%d%d%d",&x,&y,&pos);
                add(x,pos);
                add(y+1,-pos);
            }
            if(cmd==2)
            {
                scanf("%d",&pos);
                //cout<<query(y)<<" "<<query(x-1)<<endl;
                printf("%d
    ",query(pos));
            }
        }
        return 0;
    }
  • 相关阅读:
    第四周编程总结
    第三周编程总结
    第二周编程总结
    查找整数 编程总结
    求最大值及其下标 编程总结
    C语言I博客作业04
    C语言I博客作业03
    C语言I博客作业02
    作业01
    第八周作业
  • 原文地址:https://www.cnblogs.com/minun/p/10871894.html
Copyright © 2020-2023  润新知