模板——树状数组
-
有关树状数组的优质博客
彻底弄懂二维树状数组(戳我)
-
模板代码「先前」
#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;
}