问:树状数组
  • 板块学术版
  • 楼主testbot
  • 当前回复22
  • 已保存回复22
  • 发布时间2020/8/4 17:45
  • 上次更新2023/11/6 21:18:59
查看原帖
问:树状数组
334740
testbot楼主2020/8/4 17:45

在CF上看到一种不同于lowbit的写法:

#include<bits/stdc++.h>
#define ll long long
#define N 500000 
using namespace std;
int n,q;
struct Tree{
    ll tree[N+5];
    inline void add(int x,ll d){
    	for(;x<=N;x |= (x+1)) tree[x] = (tree[x]+d);
    }
    inline ll query(int x){
    	long long ans = 0;
        for(;x>=0;x = (x&(x+1))-1) ans += tree[x];
        return ans;
    }
}tree;
int main(){
	scanf("%d%d",&n,&q);
	ll x;
	for(int i = 1;i<=n;++i) scanf("%lld",&x),tree.add(i,x);
	int opt,l,r;
	while(q--){
		scanf("%d%d",&opt,&l);
		if(opt == 1){
			scanf("%lld",&x);
			tree.add(l,x);
		}else{
			scanf("%d",&r);
			printf("%lld\n",tree.query(r)-tree.query(l-1));
		}
	}
	return 0;
}  

这是我写的lowbit做法:

#include<bits/stdc++.h>
#define ll long long
#define N 500000 
using namespace std;
int n,q;
inline int lowbit(int x){
	return x&-x;
}
struct Tree{
    ll tree[N+5];
    inline void add(int x,ll d){
    	while(x<=n){
    		tree[x] = (tree[x]+d);
    		x += lowbit(x);
    	}
    }
    inline ll query(int x){
    	long long ans = 0;
    	while(x>0){
    		ans += tree[x];
    		x -= lowbit(x);
    	}
        return ans;
    }
}tree;
int main(){
	scanf("%d%d",&n,&q);
	ll x;
	for(int i = 1;i<=n;++i) scanf("%lld",&x),tree.add(i,x);
	int opt,l,r;
	while(q--){
		scanf("%d%d",&opt,&l);
		if(opt == 1){
			scanf("%lld",&x);
			tree.add(l,x);
		}else{
			scanf("%d",&r);
			printf("%lld\n",tree.query(r)-tree.query(l-1));
		}
	}
	return 0;
} 

实测发现,第一种写法比第二种写法快,求问原因。

2020/8/4 17:45
加载中...