搞了好长时间,终于把这题弄懂了,下面下面就分享一下自己的做题心得吧!
题目大意:题目分析:主要运用线段树求某段区间的和;设置
错误分析:1.在函数CreatTree()中(1)出现了问题,应mid+1;
2.mian函数中(2)出现问题,要用到循环
#include<cstdio> #include<iostream> #include<cstring> using namespace std; #define MAX 50005 struct segtree { int l,r,sum; }tree[200005]; int n,y[MAX]; void CreatTree(int s,int e,int t) //创建树结点 { tree[t].l=s; tree[t].r=e; tree[t].sum=0; int temp=t<<1;//temp只是标记树下标的; if(s==e) //若区间端点相同则把数组y[i]中赋值给叶子结点为i-i的结点 { tree[t].sum=y[e]; } else { int mid=(s+e)>>1; CreatTree(s,mid,temp);//创建左子树 CreatTree(mid+1,e,temp+1);//此时右子树的区间是mid+1,不是mid (1) tree[t].sum=tree[temp].sum+tree[temp+1].sum; } } void Update(int pos,int t,int valu) //更新数据,Add,Sub命令都可以用此函数, { int temp=t<<1; if(tree[t].l==pos&&tree[t].r==pos) //若结点匹配则修改 { tree[t].sum+=valu; } else { int mid=(tree[t].l+tree[t].r)>>1; if(pos<=mid)//在左子树上查询修改 Update(pos,temp,valu); else Update(pos,temp+1,valu); tree[t].sum=tree[temp].sum+tree[temp+1].sum;修改时要把 } } int Query(int s,int e,int t) //询问,计算询问区间的总数 { int temp=t<<1; if(s<=tree[t].l&&e>=tree[t].r) { return tree[t].sum; } else { int mid=(tree[t].r+tree[t].l)>>1; int sum1=0,sum2=0; if(s<=mid)//计算左子树的总数 sum2=Query(s,e,temp); if(e>mid)//计算右子树的总数 sum1=Query(s,e,temp+1); return sum1+sum2; } } int main() { int t,i,j,a,b; char str[10]; scanf("%d\n",&t); for(i=1;i<=t;i++) { scanf("%d",&n); for(j=1;j<=n;j++) scanf("%d",&y[j]); CreatTree(1,n,1); printf("Case %d:\n",i); while(1)//需要用到循环,可以执行多条命令 (2) { scanf("%s",str); if(strcmp(str,"End")==0)break; scanf("%d%d",&a,&b); if(strcmp(str,"Sub")==0)Update(a,1,-b); else if(strcmp(str,"Add")==0)Update(a,1,b); else printf("%d\n",Query(a,b,1)); } } return 0; }