hdu 1166 树状数组 & 线段树
2011-07-31 11:24
363 查看
//树状数组 #include "stdafx.h" #include <iostream> using namespace std; const int MAXN = 50010; int num[MAXN]; int sum[MAXN];//sum[i]: lowbit为i的二进制表示中右边第一个1所代表的数字,然后sum[i]里存的就是从num[i]开始向前数lowbit个元素之和 int n; int lowbit(int x) //取x的最低位 { return x&(-x); } void add(int i, int val) //将第i个元素增加val { //i的祖先都增加val while(i <= n) { sum[i] += val; i += lowbit(i); //将i的二进制未位1补为0得到其父亲 } } int Sum(int i) //求前i项的和 { int s = 0; //将前i项分段 while(i > 0) { s += sum[i]; i -= lowbit(i); //去掉i的二进制最后一个1 } return s; } int main() { int t; char order[10]; int a,b; cin>>t; for(int Case=1; Case<=t; Case++) { memset(sum,0,sizeof(sum)); cout<<"Case "<<Case<<":"<<endl; cin>>n; for(int i=1; i<=n; i++) { cin>>num[i]; add(i,num[i]); } while(1) { cin>>order; if(strcmp(order,"End") == 0) { break; } cin>>a>>b; if(strcmp(order,"Query") == 0) { cout<<Sum(b)-Sum(a-1)<<endl; } if(strcmp(order,"Add") == 0) { add(a,b); } if(strcmp(order,"Sub") == 0) { add(a,-b); } } } return 0; }
//线段树,hdu 1166,节点更新,区间求和 #include <iostream> using namespace std; const int MAXN = 50000 + 100; struct treeNode { int left; int right; int num; }node[MAXN*3]; int num[MAXN]; int buildTree(int low, int top, int index) //功能:建树.父节点是左右子节点之和 { node[index].left = low; node[index].right = top; if (low == top) //是否已经递归到最低层 { node[index].num = num[low]; return node[index].num; } int mid = (low + top) / 2; node[index].num = buildTree(low,mid,index*2) + buildTree(mid+1,top,index*2+1); //父节点为左右子节点之和 return node[index].num; } void update(int k, int num, int index) { node[index].num = node[index].num + num; //每一个覆盖的区间都加上num if (node[index].left == node[index].right && node[index].left == k) //已经更新到最底层并且找到K点 { return; } int mid = (node[index].left + node[index].right) / 2; if (k <= mid) //如果k在左子树中 { update(k,num,index*2); } else //如果k在右子树中 { update(k,num,index*2+1); } } int search(int low, int top, int index) { if (node[index].left == low && node[index].right == top) //找到完全重合的区间,直接返回该值,即为本次搜索的最终结果 { return node[index].num; } int mid = (node[index].left + node[index].right) / 2; if (top <= mid) //搜索区间位于左子树 { return search(low,top,index*2); } else if(low > mid) //搜索区间位于右子树 { return search(low,top,index*2+1); } else //搜索区间在左右子树间,即将区间分成2部分 { return search(low,mid,index*2) + search(mid+1,top,index*2+1); } } int main() { int t; int n; cin>>t; char command[10]; int a,b; for (int Case=1; Case<=t; Case++) { cin>>n; for (int i=1; i<=n; i++) { cin>>num[i]; } buildTree(1,n,1); cout<<"Case "<<Case<<":"<<endl; while (1) { cin>>command; if(command[0] == 'E') { break; } cin>>a>>b; if (command[0] == 'Q') { cout<<search(a,b,1)<<endl; } else if (command[0] == 'A') { update(a,b,1); } else if (command[0] == 'S') { update(a,-b,1); } } } return 0; }
相关文章推荐
- hdu 1166 敌兵布阵【入门线段树 & 树状数组】
- HDU 1166 敌兵布阵 (线段树基础&树状数组基础)
- HDU 1166 敌兵布阵 树状数组||线段树
- hdu 1166 树状数组 线段树入门
- hdu 1166(树状数组 或 线段树)
- hdu 1166 线段树与树状数组入门 单点更新
- HDU 1394 (树状数组 & 线段树 两种做法)
- HDU Problem 1166 敌兵布阵 【树状数组 & 线段树】
- HDU 1166.敌兵布阵【线段树】【树状数组】【4月27】
- HDU 1166 敌兵布阵【树状数组】【线段树】
- HDU 1166 敌兵布阵(树状数组||线段树单点更新)
- HDU 1166 敌兵布阵 (树状数组 || 线段树)
- hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)
- HDU - 1166 - 敌兵布阵(树状数组、线段树)
- 【HDU】-1166-敌兵布阵(树状数组,线段树)
- HDU - 1166 - 敌兵布阵 (树状数组 or 线段树)
- hdu 1166 线段树树状数组 Java解法
- HDU-1166 敌兵布阵 (树状数组 or 线段树)
- hdu 1166 树状数组 线段树
- HDU 1556 前缀和 & 树状数组 & 线段树