hdu_1166 敌兵布阵(线段树)
2013-07-19 16:42
471 查看
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166
分析:用数组解这道题,果断超时。传说中的线段树入门题-,-。
线段树基础可以点这里
我的代码(线段树):
总结:好久好久以前就遇到这样的题目了,一直没有勇气做,今天终于鼓起勇气做线段树o(≧v≦)o~~
今天来看这个代码··觉得好搓呀,来一个不怎么搓的 o(≧v≦)o~~
分析:用数组解这道题,果断超时。传说中的线段树入门题-,-。
线段树基础可以点这里
我的代码(线段树):
#include<stdio.h> #define max 50000 struct Node { int left; int right; int sum; }segTree[4*max+10]; int p[max+10]; void CreatsegTree(int index,int lef,int rig) //创建一个[lef,rig]的线段树。 { segTree[index].left=lef; segTree[index].right=rig; if(lef==rig) { segTree[index].sum=p[lef]; return; } int mid=(lef+rig)>>1; int nindex=index<<1; CreatsegTree(nindex,lef,mid); CreatsegTree(nindex+1,mid+1,rig); segTree[index].sum=segTree[nindex].sum+segTree[nindex+1].sum; } void serTree(int index,int k,int num) //更新[k,k]的位置更新线段树的值。 { if(k==segTree[index].left&&k==segTree[index].right) //找到[k,k]为更新。 { segTree[index].sum+=num; return; } int mid=(segTree[index].left+segTree[index].right)>>1; if(k<=mid) { serTree(index*2,k,num); segTree[index].sum+=num; //底层的位置数更新了,上层的一起更新。 } else { serTree(index*2+1,k,num); segTree[index].sum+=num; //底层的位置数更新了,上层的一起更新。 } } int ans=0; void Query(int index,int a,int b) //计算[a,b]段的和。 { int mid=(segTree[index].left+segTree[index].right)>>1; if(segTree[index].left==a&&segTree[index].right==b) { ans+=segTree[index].sum; return; } if(segTree[index].left==segTree[index].right) return; if(b>mid&&a>mid) Query(index*2+1, a, b); else if(a<=mid&&b<=mid) Query( index*2, a, b); else { Query( index*2, a, mid); Query( index*2+1, mid+1, b); } } int main() { int t; scanf("%d",&t); int cas=1; while(t--) { int n,i; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",p+i); CreatsegTree(1,1,n); char str[10]; printf("Case %d:\n",cas++); while(~scanf("%s",str)&&str[0]!='E') { int a ,b; scanf("%d%d",&a,&b); ans=0; switch(str[0]) { case 'A': serTree( 1, a,b);break; case 'S': serTree( 1, a,-b);break; case 'Q': Query(1, a, b); printf("%d\n",ans); break; } } } return 0; }
总结:好久好久以前就遇到这样的题目了,一直没有勇气做,今天终于鼓起勇气做线段树o(≧v≦)o~~
今天来看这个代码··觉得好搓呀,来一个不怎么搓的 o(≧v≦)o~~
#include<stdio.h> #define MAXN 50000 struct Node { int left; int right; int sum; }segTree[4*MAXN+10]; int p[MAXN+10]; void CreatsegTree(int index,int lef,int rig) //创建一个[lef,rig]的线段树。 { segTree[index].left=lef; segTree[index].right=rig; if(lef==rig) { segTree[index].sum=p[lef]; return; } int mid=(lef+rig)>>1; CreatsegTree(index<<1,lef,mid); CreatsegTree(index<<1|1,mid+1,rig); segTree[index].sum=segTree[index<<1].sum+segTree[index<<1|1].sum; } void ModfiyTree(int index,int k,int num) //更新[k,k]的位置更新线段树的值。 { if(segTree[index].left==k&&k==segTree[index].right) //找到[k,k],更新。 { segTree[index].sum+=num; return; } int mid=(segTree[index].left+segTree[index].right)>>1; if(k<=mid) { ModfiyTree(index*2,k,num); segTree[index].sum+=num; //底层的位置数更新了,上层的一起更新。 } else { ModfiyTree(index*2+1,k,num); segTree[index].sum+=num; //底层的位置数更新了,上层的一起更新。 } } //int ans; int Query(int index,int a,int b) //计算[a,b]段的和。 { if(segTree[index].left==a && segTree[index].right==b) { return segTree[index].sum; } //当左右端点相等的时候,即到了叶子结点的位置,要返回了。 if(segTree[index].left==segTree[index].right) { return 0; } int mid=(segTree[index].left+segTree[index].right)>>1; if(b<=mid) Query( index<<1, a, b); else if(a>mid) Query(index<<1|1, a, b); else { return Query( index<<1, a, mid)+Query( index<<1|1, mid+1, b); } } int main() { int t; scanf("%d",&t); int cas=1; while(t--) { int n,i; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",p+i); CreatsegTree(1,1,n); char str[10]; printf("Case %d:\n",cas++); while(~scanf("%s",str)&&str[0]!='E') { int a ,b; scanf("%d%d",&a,&b); switch(str[0]) { case 'A': ModfiyTree( 1, a,b);break; case 'S': ModfiyTree( 1, a,-b);break; case 'Q': printf("%d\n",Query(1, a, b)); break; } } } return 0; }
相关文章推荐
- hdu 1166 敌兵布阵 (线段树)
- hdu-1166敌兵布阵(线段树 部分数据的更新及求和)
- hdu 1166 敌兵布阵(线段树)
- HDU 1166 敌兵布阵(线段树基础)
- HDU 1166 敌兵布阵 线段树
- hdu 1166 敌兵布阵(线段树点区)
- hdu 1166敌兵布阵 线段树 树状数组
- HDU 1166 敌兵布阵 【线段树(单点增减 区间求和)】
- HDU 1166 敌兵布阵【线段树,树状数组入门题,单点更新,区间求和】
- 【线段树 + 简单题】杭电 hdu 1166 敌兵布阵
- HDU 1166 敌兵布阵(区间求和&(线段树|树状数组))
- HDU - 1166 敌兵布阵 线段树区间查询
- HDU 1166 敌兵布阵【线段树-单点更新】
- HDU 1166 敌兵布阵 (线段树入门_纪念一下)
- HDU 1166 敌兵布阵 (线段树点更新区间查询)
- hdu 1166 敌兵布阵(线段树,树状数组)
- HDU 1166:敌兵布阵(线段树入门)
- HDU-1166敌兵布阵(线段树)
- HDU - 1166 敌兵布阵(线段树)
- 敌兵布阵 HDU - 1166 (线段树单点更新)