树状数组—改段求点

来源:互联网 发布:淘宝客服骂人怎么投诉 编辑:程序博客网 时间:2024/05/21 22:41

对于更改一段区间的值,然后求出某个点的值的问题,我们可以先记录它的第一个量,后面记录的差值c[ i ] = a[ i ] - a[ i-1 ]),所以a[ i ] = a[ i-1 ] + c[ i ]。这样就可以利用树状数组求和快的特点,迅速求出其值。

在更新时也只需要改区间头的c值 以及区间尾+1的c值 即可。


例题:(来源: codevs 1081)

给你N个数,有两种操作
1:给区间[a,b]的所有数都增加X
2:询问第i个数是什么。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n,m;int c[100010];int lowbit(int x){return x&-x;}void add(int x,int k){while(x<=n){c[x]+=k;x+=lowbit(x);}}int wen(int x){int s=0;while(x>=1){s+=c[x];x-=lowbit(x);}return s;}int main(){memset(c,0,sizeof(c));scanf("%d",&n);int x,y;scanf("%d",&x);add(1,x);for(int i=2;i<=n;i++){scanf("%d",&y);add(i,y-x);//存两个之差x=y;}scanf("%d",&m);for(int i=1;i<=m;i++){int o,x,y,z;scanf("%d",&o);if(o==1){scanf("%d%d%d",&x,&y,&z);add(x,z);add(y+1,-z);//改变头和尾+1}else{scanf("%d",&x);int ans=wen(x);printf("%d\n",ans);}}return 0;}

0 0
原创粉丝点击