前缀和 与 树状数组
通常情况下,树状数组可用来处理单点修改,区间查询。 通过前缀和的转换,可以使其处理区间修改和单点查询。
考虑原数组和前缀和数组:
修改原数组的某个点(i) 等价于 修改前缀和数组 的一条线段(1~i 都要修改)
查询原数组的某条线段(1~i) 等价于 查询前缀和数组的一个点(i)
这样,适当地处理前缀和数组和原数组,就可以转化两种问题。
通常情况下,对于A,我们会计算其前缀和数组B,但为了转化问题,也可以把A看做B的前缀和数组。(这里运用BIT时就出现了所谓的 “ 前缀和的前缀和 “)
附上树状数组的模板:单点修改,区间查询
一维(标准)
#define lowbit(i) ((i)&(-i)) struct BIT{ int t[R][C]; int query(int x){ int ret=0; for (int i=x;i>0;i-=lowbit(i)) ret+=t[i]; return ret; } void add(int x,int val){ for (int i=x;i<=m;i+=lowbit(i)) t[i]+=val; } };
多维(扩展)
#define lowbit(i) ((i)&(-i)) struct BIT{ int t[R][C]; int query(int x,int y){ int ret=0; for (int i=x;i>0;i-=lowbit(i)) for (int j=y;j>0;j-=lowbit(j)) ret+=t[i][j]; return ret; } void add(int x,int y,int val){ for (int i=x;i<=m;i+=lowbit(i)) for (int j=y;j<=n;j+=lowbit(j)) t[i][j]+=val; } };
使用时不要忘记初始化。初始化的方法就是把每个点都插入一遍。
还要注意BIT查询时的返回值是前缀和。
wsc500原创,转载请注明出处。请注明 出自http://www.cnblogs.com/loveidea/