初学线段树:hdu1166 敌兵布阵,请求优化与改正
这是学了线段树后第一次做实题,提交的时候是栈溢出。
代码完全是按那种标准模式写的,对线段树的理解也不是很够,想要借助这次机会深入理解线段树,希望各位能给一些宝贵意见优化改正!
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=1166
代码:
#include <iostream>#include <cstring>#define maxn 50001using namespace std;int tail,Sum,a[maxn];struct node{ int a,b,sum; int lc,rc;} tree[2*maxn];void Build_Tree(int a1,int b1){ tail++; int now=tail; tree[now].a=a1;tree[now].b=b1; tree[now].sum=0; tree[now].lc=tree[now].rc=-1; int mid=(a1+b1)>>1; if (a1+1<b1) { tree[now].lc=tail+1;Build_Tree(a1,mid); tree[now].rc=tail+1;Build_Tree(mid,b1); tree[now].sum=tree[tree[now].lc].sum+tree[tree[now].rc].sum; } else if (a1+1==b1) tree[now].sum=a[b1];}void modify(int now,int left,int right,int st){ int a1=tree[now].a,b1=tree[now].b; if (a1==left && b1==right) { tree[now].sum+=st; return ; } int mid=(a1+b1)>>1; int lcd=tree[now].lc,rcd=tree[now].rc; if (right<=mid) { modify(lcd,left,right,st); tree[now].sum=tree[lcd].sum+tree[rcd].sum; } else if (left>=mid) { modify(rcd,left,right,st); tree[now].sum=tree[lcd].sum+tree[rcd].sum; } else { modify(lcd,left,mid,st); modify(rcd,mid,right,st); tree[now].sum=tree[lcd].sum+tree[rcd].sum; }}void getsum(int now,int left,int right){ int a1=tree[now].a,b1=tree[now].b; if (a1==left && b1==right) { Sum+=tree[now].sum; return ; } int mid=(a1+b1)>>1; int lcd=tree[now].lc,rcd=tree[now].rc; if (right<=mid) { getsum(lcd,left,right); } else if (left>=mid) { getsum(rcd,left,right); } else { getsum(lcd,left,mid); getsum(rcd,mid,right); }}int main(){ int T,n; cin>>T; for (int i=1;i<=T;++i) { cin>>n; for (int j=1;j<=n;++j) cin>>a[j]; cout<<"Case "<<i<<":"<<endl; Build_Tree(0,n); char ss[10];int t1,t2; while (1) { cin>>ss; if (!(strcmp(ss,"End")))break; cin>>t1>>t2; if (!(strcmp(ss,"Add"))) modify(1,t1-1,t1,t2); else if (!(strcmp(ss,"Sub"))) modify(1,t1-1,t1,-t2); else { Sum=0; getsum(1,t1-1,t2); cout<<Sum<<endl; } } } return 0;}