http://acm.hdu.edu.cn/showproblem.php?pid=1166
***********************************************************
本人做的第一道線段樹的題,紀念一下吧
***********************************************************
/**********************************Accepted 1166 46MS 2476K 1572 B C++**********************************/#include<iostream>using namespace std;struct node{int left,right,mid;int num;//該結點士兵數}a[150000];//通常3*n的空間就okint st[50010],sum;void creat(int s,int t,int step)//建樹{a[step].left=s;a[step].right=t;a[step].mid=(s+t)/2;if(s==t){a[step].num=st[t];return ;}creat(s,a[step].mid,2*step);creat(a[step].mid+1,t,2*step+1);a[step].num=a[2*step].num+a[2*step+1].num;}void add(int ans1,int ans2,int step)//Sub & Add函數{a[step].num+=ans2;//為啥要放在這裡?因為每棵子樹都是內含項目關聯性,看看線段樹就知道了,【這裡每個節點都儲存了子樹士兵的和】if(a[step].left==a[step].right){return ;}if(ans1<=a[step].mid)add(ans1,ans2,2*step);elseadd(ans1,ans2,2*step+1);}void find(int s,int t,int step){if(s==a[step].left && t==a[step].right){sum+=a[step].num;return ;}//詢問時遇到匹配的線段就return!if(t<=a[step].mid)find(s,t,2*step);elseif(s>a[step].mid)find(s,t,2*step+1);else{find(s,a[step].mid,2*step);find(a[step].mid+1,t,2*step+1);}}int main(){freopen("a.txt","r",stdin);int ca;while(scanf("%d",&ca)!=EOF){int nca;for(nca=1;nca<=ca;nca++){printf("Case %d:\n",nca);int n;scanf("%d",&n);int i;for(i=1;i<=n;i++)scanf("%d",&st[i]);creat(1,n,1);char str[10];while(scanf("%s",str)){if(str[0]=='E')break;int ans1,ans2;scanf("%d%d",&ans1,&ans2);if(str[0]=='A')add(ans1,ans2,1);if(str[0]=='S')//減的時候可以取負再調用add函數{ans2=-ans2;add(ans1,ans2,1);}if(str[0]=='Q'){sum=0;find(ans1,ans2,1);printf("%d\n",sum);}}}}return 0;}
貼一個樹狀數組的
#include <iostream>using namespace std;int tree[50005];int n;int Lowbit(int k){ return k&(-k); //return k&(k^(k-1));}int Sum(int a){ int result = 0; while(a != 0) { result += tree[a]; a -= Lowbit(a); } return result;}void Modify(int a,int c,int n){ while(a<=n) { tree[a] += c; a +=Lowbit(a); }}int main(){freopen("a.txt","r",stdin); int i,j,k; int Tcase=0; int Case; char ch[10]; scanf("%d",&Case); while(Case--) { printf("Case %d:\n",++Tcase); memset(tree,0,sizeof(tree)); scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&k); Modify(i,k,n); } while(1) { scanf("%s",&ch); if(ch[0]=='E')break; scanf("%d%d",&i,&j); if(ch[0]=='Q') printf("%d\n",Sum(j)-Sum(i-1)); else if(ch[0]=='A') Modify(i,j,n); else if(ch[0]=='S') Modify(i,-j,n); } } return 0;}