您的位置:首页 > 运维架构

树状数组区间维护及单点查询

2015-08-10 20:13 399 查看

树状数组区间维护

d[i]表示a[i]-a[i-1]的值

原理:http://wenku.baidu.com/link?url=WAxUY51ZHipbib4RyxMqhoujjcehIkWSTBxFF1Z8sjCToih7npdGhCg_HW2oKLqH3vRsQEO_QAUVYi7l6WPGFYV4WAMaWxeSPfFg4tIDXfe

#include<cstdio>

#define M 400500

using namespace std;

long long n,a[M],d[M],c1[M],c2[M],m,k,x,y,l,r;

long long lowbit(long long i){

 return i&(-i);

}

void update(long long l,long long x){

 long long k=l;

 while(k<=n){

  c1[k]+=x;

  c2[k]+=x*l;

  k+=lowbit(k);

 }

 return ;

}

long long sum(long long i){

 long long s=0,s1=0,s2=0,p=i;

 while(p>0){

  s1+=c1[p];

  s2+=c2[p];

  p-=lowbit(p);

 }

 s=s1*(i+1)-s2;

 return s;

}

int main(){

 scanf("%I64d",&n);

 for(int i=1;i<=n;i++){

  scanf("%I64d",&a[i]);

  d[i]=a[i]-a[i-1];

  for(int j=i-lowbit(i)+1;j<=i;j++){

   c1[i]+=d[j];

   c2[i]+=d[j]*j;

  }

 }

 scanf("%I64d",&m);

 for(int i=1;i<=m;i++){

  scanf("%I64d",&k);

  if (k==1){

   scanf("%I64d%I64d%I64d",&l,&r,&x);

   d[l]+=x,d[r+1]-=x;

   update(l,x);

   update(r+1,-x);

  }

  else{

   scanf("%I64d%I64d",&l,&r);

   printf("%I64d\n",sum(r)-sum(l-1));//查询点i即输出sum(i)-sum(i-1)即可

  }

 }

 return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: