您的位置:首页 > 其它

整理的树状数组模板 & 敌兵布阵 HDU - 1166

2017-03-26 11:21 585 查看
题目链接: HDU-1166 参考资料:夜深人静写算法三树状数组学习小结树状数组 ( Binary Indexed Tree,BIT,二分索引树 ),基本操作是操作线性表的数据的。两个链接都写得很详细,这里给出一些帮助理解和要注意的要点:下标index由1开始下标为 i ,i 后面有 k 个 0 就管理 2^k 个 Ai,下标为奇数的,只管理一个Ailowbit() 获取最右端的1 有 lowbit(6) == 2 // 6 的二进制是 110,2 的二进制是 10Ci的最右数字是AiCi = sum{ A[j] | i - 2^k + 1 <= j <= i } (帮助理解:将j的两个端点相减+1 等于2^k)modify() 在构建数组 Ci 和操作数据时都有用到pos + pos & (-pos) 是 pos 的父节点// pos + lowbit( pos )
void modify(int pos,int num){   //pos为数组下标位置,num为要增加的值
while(pos<=n){  //n 为数组长度 观察到pos递增
c[pos]+=num;
pos+=lowbit(pos);
}
return ;
}
pos - pos & (-pos) 是 pos 的下一个无关联节点 // pos - lowbit( pos )
int sum(int pos){  // Sum{1 to pos}
int summ=0;
while(pos>0){ //pos递减
summ+=c[pos];
pos-=lowbit(pos);
}
return summ;
}
贴代码:大意:模拟单点更新(Add , Sub),区间求值(Query):Sample Input1101 2 3 4 5 6 7 8 9 10Query 1 3Add 3 6Query 2 7Sub 10 2Add 6 3Query 3 10EndSample OutputCase 1:63359
#include <iostream>
#include<cstring>
#include<string>
using namespace std;
const int maxn =50010;
#define mem(s,t) memset(s,t,sizeof(s));
int c[maxn],a[maxn];
int n;
int lowbit(int x){
return x&(-x);
}
void modify(int pos,int num){ //pos为数组下标位置,num为要增加的值 while(pos<=n){ //n 为数组长度 观察到pos递增 c[pos]+=num; pos+=lowbit(pos); } return ; }
int sum(int pos){ // Sum{1 to pos} int summ=0; while(pos>0){ //pos递减 summ+=c[pos]; pos-=lowbit(pos); } return summ; }int main(int argc, char *argv[])
{
int T,kase=0;
scanf("%d",&T);
while(T--){
mem(a,0);mem(c,0);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
modify(i,a[i]);
}
printf("Case %d:\n",++kase);
char ch[25];
int l,r;
while(scanf("%s",&ch)){
if(strcmp(ch,"End")==0) break;
scanf("%d%d",&l,&r);
switch(ch[0]){
case 'Q':
printf("%d\n",sum(r)-sum(l-1));
break;
case 'A':
modify(l,r);
break;
case 'S':
modify(l,-r);
break;
}
}
}
return 0;
}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  树状数组 复查题