题目:略;;
思路:根据数据的结构太大,实现的功能复杂,即一般的代码达不到效果,而且运行时间可能会加长等等情况!
因此这里就需要运用到树状数组,根节点去寻找所需的值。
因此首先就要把所需的数据建立在一棵树上,即所谓建树,建好之后呢!在分类功能,根据那你所需的,分别写出功能。具体要主要的事项见代码:
#include<iostream>
#include<cstdio>
#i#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
# define manx 50005
using namespace std;
int a[manx],sum[manx*4];
void make_tree(int l,int r,int rt)***//建树。
{
if(l==r)
{
sum[rt]=a[l];
return ;
}
int mind=(l+r)>>1;
make_tree(l,mind,rt*2);//建立左孩子,
make_tree(mind+1,r,rt*2+1);//建立右孩子。
sum[rt]=sum[rt*2]+sum[rt*2+1];//得出数据的总和。
}
int quary(int l,int r,int rt,int x,int y)******//注意这里是要返回值得,要用(int),
{
if(x<=l&&y>=r)
{
return sum[rt];
}
int mind=(l+r)>>1;
if(x>mind) quary(mind+1,r,rt*2+1,x,y);//注意区间的范围是否可以取得相等??
else if(y<=mind) quary(l,mind,rt*2,x,y);//此处只有这里可以取得(=),上面不可,因为右孩子开始时为(mind+1).
else
{
int t1=quary(l,mind,2*rt,x,mind);
int t2=quary(mind+1,r,2*rt+1,mind+1,y);//此处注意区间,不可以是下面的,因为所求的和,是给定的区间,不是所有数据和。
//int x1=quary(l,mind,rt*2,x,y);//而且这区间不在同一区间,分别在两边。注意。。易错处。。。
//int y1=quary(mind+1,r,rt*2+1,x,y);
return t1+t2;
}
}
void update(int l,int r,int rt,int x,int y)
{
if(l==r)
{
sum[rt]+=y;
return ;
}
int mind=(l+r)>>1;
if(x<=mind) update(l,mind ,rt*2,x,y);
else
update(mind+1,r,rt*2+1,x,y);
sum[rt]=sum[rt*2]+sum[rt*2+1];
}
int main()
{
int n, t,i,k=0;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
make_tree(1,n,1);
printf("Case: %d\n",++k);
char str[10];
while(cin>>str&&str[0]!='E')
{
int a,b;
scanf("%d%d",&a,&b);
if(stricmp(str,"Query")==0)
printf("%d\n",quary(1,n,1,a,b));
else
{
if(str[0]=='S')
b*=-1;//注意在删除时要改变符号,。。
update(1,n,1,a,b);
}
}
}
return 0;
}