题意
如题,已知一个数列,你需要进行下面两种操作:
1.将某区间每一个数数加上x
2.求出某一个数的和
思路
用树状数组记录这个数列的差分数组,例如a[]={3,2,7,6,8}这个数列的差分数组为{3,-1,5,-1,2},我们可以从这个差分数组看出,第i个数的值就是差分数组的前i个的和。当我们进行修改,例如给2~4加上3,那么差分数组就会变成{3,2,5,-1,0},可以发现只是第2个和第5个变了,因为2~4中同时加上了2,所以它们的差分数组不会变,只会影响到它们两边的差分数组。修改的时候输出这个数的差分数列的前缀和就好了。
代码
#include<cstdio>
int n,m,tree[500001],z,x,y,last;
inline int lowbit(int x)
{
return x&-x;
}
void insert(int p,int v)
{
for (;p<=n;p+=lowbit(p))
tree[p]+=v;
}
int find(int a)
{
int o=0;
for (;a;a-=lowbit(a)) o+=tree[a];
return o;
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
{
scanf("%d",&x);
insert(i,x-last);
last=x;
}
for (int i=1;i<=m;i++)
{
scanf("%d",&z);
if (z==1)
{
scanf("%d%d%d",&x,&y,&z);
insert(x,z);//左边的差分数组发生变化
insert(y+1,-z);//右边的差分数组因为受到左边的影响所以加上-z
}
else
{
scanf("%d",&x);
printf("%d\n",find(x));//差分数组的前缀和就为这个数
}
}
}