模板——树状数组

  • 有关树状数组的优质博客

    彻底弄懂二维树状数组(戳我)

  • 模板代码「先前」

#include<iostream>
#include<cstdio>

using namespace std;

//快读
inline void read(int &x)
{
    x=0;short flag(1);char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-') flag=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+ch-48;
        ch=getchar();
    }
    x*=flag;
}

//快写
inline void write(int x)
{
    if(x<0)
    {
        x=-x;
        putchar('-');
    }
    if(x>9) write(x/10);
    putchar(x%10+48);
}

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

//一维-单点修改
inline void update_value(int x,int k)
{
    while(x<=n)
    {
        tree[x]+=k;
        x+=lowbit(x);
    }
}

//二维-单点修改
inline void update_value(int x,int y,int k)
{
    int tempy;
    while(x<=n)
    {
        tempy=y;
        while(tempy<=m)
        {
            tree[x][tempy]+=k;
            tempy+=lowbit(y);
        }
        x+=lowbit(x);
    }
}

//一维-更新最大值
inline void update_max(int x,int k)
{
    while(x<=n)
    {
        tree[x]=max(tree[x],k);
        x+=lowbit(x);
    }
}

//二维-更新最大值
inline void update_max(int x,int y,int k)
{
    while(x<=n)
    {
        int tempy=y;
        while(tempy<=n)
        {
            tree[x][y]=max(tree[x][y],k);
            tempy+=lowbit(y);
        }
        x+=lowbit(x);
    }
}

//一维-查询前缀和
inline int query_sum(int x)
{
    int res=0;
    while(x>0)
    {
        res+=tree[x];
        x-=lowbit(x);
    }
    return res;
}

//二维-查询前缀和
inline int query_sum(int x,int y)
{
    long long res=0;
    int tempy;
    while(x>0)
    {
        tempy=y;
        while(tempy>0)
        {
            res+=tree[x][tempy];
            tempy-=lowbit(y);
        }
        x-=lowbit(x);
    }
    return res;
}

//一维-查询最大值
inline int query_max(int x)
{
    int res=-0x7f7f7f;
    while(x>0)
    {
        res=max(res,tree[x]);
        x-=lowbit(x);
    }
    return res;
}

//二维-查询最大值
inline int query_max(int x,int y)
{
    int res=-0x7f7f7f7f;
    while(x>0)
    {
        int tempy=y;
        while(tempy>0)
        {
            res=max(res,tree[x][y]);
            tempy-=lowbit(y);
        }
        x-=lowbit(x);
    }
    return res;
}

//一维-单点查询
inline int query_value(int x)
{
    int res=tree[x];
    int lca=x-lowbit(x);
    x--;
    while(x!=lca)
    {
        res-=tree[x];
        x-=lowbit(x);
    }
    return res;
}
  • 模板代码「现在」

(感谢hyl大佬的指导)

#include<iostream>
#include<cstdio>
//宏定义lowbit 
#define lowbit(x) ((x)&(-x))

using namespace std;

int n;
int tree[10100];

//快读 
template<typename type>
inline void read(type &x)
{
    x=0;short flag(1);char ch=getchar();
    while(!isdigit(ch))
    {
        ch=='-'?flag=-1:0;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    flag-1?x=-x:0;
}

//快写 
template<typename type>
inline void write(type x)
{
    putchar(',');
    x<0?x=-x,putchar('-'):0;
    static short stack[30],top=0;
    do 37     {
        stack[++top]=x%10;
        x/=10;
    }while(x);
    while(top) putchar(stack[top--]|48);
    
    puts("");
}

//一维
//单点修改 
inline void update(int x,int k)
{
    for(int i=x;i<=n;i+=lowbit(i)) tree[x]+=k;
}

//前缀和查询 
inline int query_sum(int x)
{
    int res=0;
    for(int i=x;i>0;i-=lowbit(i)) res+=tree[x];
    return res;
}

//单点查询 
inline int query_value(int x)
{
    int res=tree[x];
    int lca=x-lowbit(x);
    for(int i=x-1;i!=lca;i-=lowbit(i)) res-=tree[i];
    return res;
}

//单点更新最值 
inline void update_max(int x,int k)
{
    for(int i=x;i<=n;i+=lowbit(i)) tree[i]=max(tree[i],k);
}

//查询最值 
inline int query_max(int x)
{
    int res=0;
    for(int i=x;i>0;i-=lowbit(i)) res=max(res,tree[i]);
    return res;
}

//查找某个前缀和对应的前缀下标index 
inline int query_index(int value)
{
    int index=0;
    int mask=log2(n);
    while(mask!=lca)
    {
        find=index+mask;
        if(value>=tree[find])
        {
            index=find;
            value-=tree[find];
        }
        mask/=2;//通过二分步长mask进行二分查找 
    }
}


//二维 
//单点修改 
inline void update(int x,int y,int k)
{
    for(int i=x;i<=n;i+=lowbit(i))
        for(int j=y;j<=m;j+=lowbit(j))
            tree[i][j]+=k;
}

//前缀和查询 
inline int query_sum(int x,int y)
{
    int res=0;
    for(int i=x;i>0;i-=lowbit(i))
        for(int j=y;j>0;j-=lowbit(j))
            res+=tree[i][j];
    return res;
}

//单点更新最值 
inline void update(int x,int y,int k)
{
    for(int i=x;i<=n;i+=lowbit(i))
        for(int j=y;j<=m;j+=lowbit(j))
            tree[i][j]=max(tree[i][j],k);
}

//查询最值 
inline int query_sum(int x,int y)
{
    int res=-0x7f7f7f7f;
    for(int i=x;i>0;i-=lowbit(i))
        for(int j=y;j>0;j-=lowbit(j))
            res=max(res,tree[i][j]);
    return res;
}
posted @ 2021-08-24 19:28  凌云_void  阅读(73)  评论(0编辑  收藏  举报