树状数组分析:树状数组说到底其实就是使用了lowbit()函数来进行更新和查询,这样可以让二者的时间复杂度都为O(log2n)。
lowbit(x)求的是x的二进制从右到左第一个1的那一位的权值。
本来如果用数组存着1-t的和,虽然查询是O(1)的,但是更新却是O(n)的,因此根据lowbit()函数建一个树,每次更新需要log2n次,求和也需要log2n次,极大的降低了时间复杂度。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
int a[100005];
int lowbit(int t) //返回t的二进制中,从右看第一个1的权值
{
return t&(-t);
}
void add(int t,int d) //加上数值
{
while(t<=n)
{
a[t]+=d;
t+=lowbit(t);
}
}
int getsum(int t) //得到1-t的数组和
{
int sum=0;
while(t>0)
{
sum+=a[t];
t-=lowbit(t);
}
return sum;
}
int main()
{
int d,m;
char ch[10];
int x,y;
memset(a,0,sizeof(a));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&d);
add(i,d);
}
scanf("%d",&m);
while(m--)
{
scanf("%s %d %d",ch,&x,&y);
if(!strcmp(ch,"change")) //把第x个数换为y
{
add(x,y-getsum(x)+getsum(x-1));
}
else if(!strcmp(ch,"sum")) //计算x-y之间的数组和
{
printf("%d\n",getsum(y)-getsum(x-1));
}
}
return 0;
}