题目信息:点击打开链接 士兵杀敌(二)
此题为插点问线,即在某一点动态更新值,求某一区间的和。
这应该是树状数组最基础的应用了。。。
每次插入的时候向上更新树状数组的值,到求和时,两个区间的值相减就是区间和;代码如下
#include<stdio.h>
#include<string.h>
using namespace std;
int s[1000000];
int N,t;
int lowbit(int x)
{
return x&(-x);
}
void insert(int x,int w)
{
while(x<=N)
{
s[x]+=w;
x+=lowbit(x);
}
}
int get_sum(int x)
{
int sum=0;
while(x>0)
{
sum+=s[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
int i,y;
char ss[10];
scanf("%d%d",&N,&t);
for(i=1; i<=N; i++)
{
scanf("%d",&y);
insert(i,y);//初始构造树状数组
}
while(t--)
{
scanf("%s",ss);
if(ss[0]=='Q')
{
int f,e,s1=0;
scanf("%d%d",&f,&e);
printf("%d\n",get_sum(e)-get_sum(f-1));//前e项和减去前f-1项和
}
else
{
int cse,num;
scanf("%d%d",&cse,&num);
insert(cse,num);
}
}
}
题目信息:点击打开链接士兵杀敌(四)
此题为插线问点,即动态更新某一段区间的值,求某点的值。
这应该也是树状数组最基础的应用了。。。解释在代码中注释
代码如下:
#include<stdio.h>
#include<string.h>
int T,M,s[1000002];
int lowbit(int x)
{
return x&(-x);
}
void insert(int x,int y,int w)
{
//将区间x至M的区间都更新+w
while(x<=M)
{
s[x]+=w;
x+=lowbit(x);
}
//将区间y+1至M的区间都更新-w
y+=1;
while(y<=M)
{
s[y]-=w;
y+=lowbit(y);
}
}//例如:区间长度为15,在[3,10]每个数都加2就相当于在[3,15]都加上2,[11,15]都减去2.
int get_sum(int x)
{
int sum=0;
while(x>0)
{
sum+=s[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
char c[15];
memset(s,0,sizeof(s));
scanf("%d%d",&T,&M);
while(T--)
{
scanf("%s",c);
if(c[0]=='A')
{
int f,e,v;
scanf("%d%d%d",&f,&e,&v);
insert(f,e,v);
}
else
{
int m;
scanf("%d",&m);
printf("%d\n",get_sum(m));
}
}
}