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

来源:互联网 发布:网络女主播不雅视频 编辑:程序博客网 时间:2024/06/05 00:41


树状数组区间维护

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;
}

0 0
原创粉丝点击