模板 一维树状数组

单点修改,区间求和

#define lowbit(x) x&(-x)
const int maxn=100010;
int n,bit[2*maxn];

int query(int x){
	int s=0;
	while(x>0){
		s+=bit[x];
		x-=lowbit(x);
	}
	return s;
}

void change(int x,int v){
	while(x<=n){
		bit[x]+=v;
		x+=lowbit(x);
	}
}

区间修改,单点查询
    将原数组存储成差分数组,根据差分的性质,在区间[l,r]上同时加上x可以处理成:
    \(change(l,x)\)
    \(change(r+1,-x)\)
    查询下标为i的元素值可以处理成:
    \(query(i)\)
区间修改,区间求和
    设置两个BIT,bit和bit2
    在区间[l,r]上同时加上x可以处理成:
    \(change(bit,l,x)\)
    \(change(bit,r+1,-x)\)
    \(change(bit2,l,k*l)\)
    \(change(bit2,r+1,-k*(r+1))\)
    区间[l,r]的求和可以处理成:
    \(query(bit,r)*(r+1)-query(bit2,r)-(query(bit,l-1)*l-query(bit2,l-1))\)

const int maxn=100010;
LL bit[maxn],bit2[maxn];

void add(LL *t,int x,LL v){
    for(int i=x;i<=n;i+=lowbit(i)) t[i]+=v;
}

LL sum(LL *t,int x){
    LL ans=0;
    for(int i=x;i>0;i-=lowbit(i)) ans+=t[i];
    return ans;
}

void update(int l,int r,LL k){
    add(bit,l,k);
    add(bit,r+1,-k);
    add(bit2,l,k*l);
    add(bit2,r+1,-k*(r+1));
}

LL getsum(int x){
    return sum(bit,x)*(x+1)-sum(bit2,x);
}

LL query(int l,int r){
    return getsum(r)-getsum(l-1);
}
posted @ 2020-06-09 15:02  fxq1304  阅读(127)  评论(0编辑  收藏  举报