[C++] 封装树状数组

支持单点修改与区间查询的普通树状数组

  • int sum(int l,int r) 求区间 [l,r] 的和
  • void change(int id,int changevalue) 将 id 的值增加 changevalue
struct BIT{
	int n;
	int t[100001];
	inline int lowbit(int x){
		return x&-x;
	}
	void clear(){
		for(int i=1;i<=n;++i){
			t[i]=0;
		}
	}
	int sum(int end){
		int sum=0;
		for(int i=end;i;i-=lowbit(i)){
			sum+=t[i];
		}
		return sum;
	}
	int sum(int l,int r){
		return sum(r)-sum(l-1);
	}
	void change(int id,int changevalue){
		for(int i=id;i<=n;i+=lowbit(i)){
			t[i]+=changevalue;
		}
	}
};

//class操作简洁版本
class BIT{
	private:
		int t[100001];
		inline int lowbit(int x){
			return x&-x;
		}
		int sum(int end){
			int sum=0;
			for(int i=end;i;i-=lowbit(i)){
				sum+=t[i];
			}
			return sum;
		}
	public:
		int n;
		void clear(){
			for(int i=1;i<=n;++i){
				t[i]=0;
			}
		}
		int sum(int l,int r){
			return sum(r)-sum(l-1);
		}
		void change(int id,int changevalue){
			for(int i=id;i<=n;i+=lowbit(i)){
				t[i]+=changevalue;
			}
		}	
};

支持区间修改与单点查询的差分树状数组

  • void change(int l,int r,int changevalue) 将区间 [l,r] 的值增加 changevalue
  • void make_diff(int x[],int maxn) 对x[]求差分并存储
  • make_diff(int x,int last,int nown) 将x-last存储在第id位(主要用来省空间)
  • int find(int id) 查询id的值
struct D_BIT{
	int n;
	int a[100001];
	int t[100001];
	void clear(){
		for(int i=1;i<=n;++i){
			t[i]=0;
		}
	}
	inline int lowbit(int x){
		return x&-x;
	}
	void change(int id,int changevalue){
		for(int i=id;i<=n;i+=lowbit(i)){
			t[i]+=changevalue;
		}
	}
	void make_diff(int x[],int maxn){
		clear();
		for(int i=1;i<=maxn;++i){
			a[i]=x[i]-x[i-1];
			change(i,a[i]);
		}
	}
	void make_diff(int x,int last,int nown){
		a[nown]=x-last;
		change(nown,a[nown]);
	}
	void change(int l,int r,int changevalue){
		a[l]+=changevalue;
		a[r+1]-=changevalue;
		change(l,changevalue);
		change(r+1,-changevalue);
	}
	int find(int id){
		int ans=0;
		for(int i=id;i>=1;i-=lowbit(i)){
			ans+=t[i];
		}
		return ans;
	}
};

//class操作简洁版本
class D_BIT{
	private:
		int a[100001];
		int t[100001];
		inline int lowbit(int x){
			return x&-x;
		}
		void change(int id,int changevalue){
			for(int i=id;i<=n;i+=lowbit(i)){
				t[i]+=changevalue;
			}
		}
	public:
		int n;
		void clear(){
			for(int i=1;i<=n;++i){
				t[i]=0;
			}
		}
		void make_diff(int x[],int maxn){
			clear();
			for(int i=1;i<=maxn;++i){
				a[i]=x[i]-x[i-1];
				change(i,a[i]);
			}
		}
		void make_diff(int x,int last,int nown){
			a[nown]=x-last;
			change(nown,a[nown]);
		}
		void change(int l,int r,int changevalue){
			a[l]+=changevalue;
			a[r+1]-=changevalue;
			change(l,changevalue);
			change(r+1,-changevalue);
		}
		int find(int id){
			int ans=0;
			for(int i=id;i>=1;i-=lowbit(i)){
				ans+=t[i];
			}
			return ans;
		}
};

支持区间修改与区间查询的树状数组

  • int sum(int l,int r) 求区间 [l,r] 的和
  • void change(int x,int y,int changevalue) 将区间 [x,y] 的值增加 changevalue
  • void make_sum(int id,int x) 将x的值存入第id位
struct S_BIT{
	int n;
	long long d[100001],di[100001],s[100001];
	void clear(){
		memset(d,0,sizeof(d));
		memset(di,0,sizeof(di));
		memset(s,0,sizeof(s));
	}
	inline int lowbit(int x){
		return x&-x;
	}
	void change(long long *c,int x,int y){
		while(x<=n){
			c[x]+=y;
			x+=lowbit(x);
		}
	}
	long long sum(long long *c,int x){
		long long ans=0;
		while(x>0){
			ans+=c[x];
			x-=lowbit(x);
		}
		return ans;
	}
	long long sum(int end){
		return s[end]+(end+1)*sum(d,end)-sum(di,end);
	}
	long long sum(int l,int r){
		return sum(r)-sum(l-1);
	}
	void change(int x,int y,int changevalue){
		change(d,x,changevalue);
		change(d,y+1,-changevalue);
		change(di,x,changevalue*x);
		change(di,y+1,-changevalue*(y+1));
	}
	void make_sum(int id,int x){
		s[id]=s[id-1]+x;
	}
};

//class操作简洁版本
class S_BIT{
	private:
		long long d[100001],di[100001],s[100001];
		inline int lowbit(int x){
			return x&-x;
		}
		void change(long long *c,int x,int y){
			while(x<=n){
				c[x]+=y;
				x+=lowbit(x);
			}
		}
		long long sum(long long *c,int x){
			long long ans=0;
			while(x>0){
				ans+=c[x];
				x-=lowbit(x);
			}
			return ans;
		}
		long long sum(int end){
			return s[end]+(end+1)*sum(d,end)-sum(di,end);
		}
	public:
		int n;
		void clear(){
			memset(d,0,sizeof(d));
			memset(di,0,sizeof(di));
			memset(s,0,sizeof(s));
		}
		long long sum(int l,int r){
			return sum(r)-sum(l-1);
		}
		void change(int x,int y,int changevalue){
			change(d,x,changevalue);
			change(d,y+1,-changevalue);
			change(di,x,changevalue*x);
			change(di,y+1,-changevalue*(y+1));
		}
		void make_sum(int id,int x){
			s[id]=s[id-1]+x;
		}
};

终极版:全支持版本:

  • long long sum(int l,int r) 求区间 [l,r] 的和
  • long long sum(int id) 求 id 的值
  • void change(int x,int y,int changevalue) 将区间 [x,y] 的值增加 changevalue
  • void change(int id,int changevalue) 将 id 的值增加 changevalue
  • void make_sum(int id,int x) 将x的值存入第id位
class BIT{
	private:
		long long d[100001],di[100001],s[100001];
		inline int lowbit(int x){
			return x&-x;
		}
		void change(long long *c,int x,int y){
			while(x<=n){
				c[x]+=y;
				x+=lowbit(x);
			}
		}
		long long sum(long long *c,int x){
			long long ans=0;
			while(x>0){
				ans+=c[x];
				x-=lowbit(x);
			}
			return ans;
		}
		long long sum(int end){
			return s[end]+(end+1)*sum(d,end)-sum(di,end);
		}
	public:
		int n;
		void clear(){
			memset(d,0,sizeof(d));
			memset(di,0,sizeof(di));
			memset(s,0,sizeof(s));
		}
		long long sum(int l,int r){
			return sum(r)-sum(l-1);
		}
		void change(int x,int y,int changevalue){
			change(d,x,changevalue);
			change(d,y+1,-changevalue);
			change(di,x,changevalue*x);
			change(di,y+1,-changevalue*(y+1));
		}
		void make_sum(int id,int x){
			s[id]=s[id-1]+x;
		}
		long long sum(int id){
			return sum(id,id);
		}
		void change(int id,int changevalue){
			change(id,id,changevalue);
		}
};
posted @ 2024-02-18 10:05  HaneDaniko  阅读(45)  评论(4编辑  收藏  举报