【模板】树状数组

有限值域平衡树
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
enum {
	the_size = 100010
};
class BIT_TREE {
	private : 
		int num[the_size], pre[the_size];
		int maxn;
		long long sum, sizev;
		#define lowbit(x) (x&(-x))
		int query(int v) {
			int res = 0;
			for(;v > 0;v -= lowbit(v)) 
				res += pre[v];
			printf(" >> %d\n",res);
			return res;
		}
		void nadd(int v) {
			num[v]++;
		}
		void padd(int v) {
			for(;v <= maxn;v += lowbit(v)) 
				pre[v]++;
		}
		bool ndel(int v) {
			if(num[v]) {
				num[v]--;
				return true;
			}
			return false;
		}
		void pdel(int v) {
			for(;v <= maxn;v += lowbit(v)) 
				pre[v]--;
		}
		int conduct_number(int k) {
			int cnt = 0, res = 0;
			for(int i = log(maxn);~i;--i) {
				res += 1<<i;
				if(res >= maxn||cnt+pre[res] >= k) 
					res -= 1<<i;
				else 
					cnt += pre[res];
			}
			return res+1;
		}
		int conduct_rank(int k) {
			return query(k-1)+1;
		}
		#undef lowbit
	public : 
		void init(int size) {
			maxn = size;
			memset(num,0,(size+1)*sizeof(int));
			memset(pre,0,(size+1)*sizeof(int));
		}
		void Insert(int v) {
			nadd(v);
			padd(v);
			sizev++;
			sum -= v;
		}
		void Delete(int v) {
			if(ndel(v)) {
				pdel(v);
				sizev--;
				sum -= v;
			}
		}
		int Number(int k) {
			return conduct_number(k);
		}
		int Rank(int k) {
			return conduct_rank(k);
		}
		int Pre(int k) {
			return conduct_number(conduct_rank(k)-1);
		}
		int Suc(int k) {
			return conduct_number(conduct_rank(k)+num[k]);
		}
		int Max() {
			return conduct_number(sizev);
		}
		int Min() {
			return conduct_number(1);
		}
		long long Sum() {
			return sum;
		}
		double Averange() {
			return (1.0*sum/sizev);
		}//平均数;
		int FracN(int u,int d) {
			
		}//第u d分位数;
		int Mid() {
			return FracN(1,2);
		}//中位数;
		int Com() {
			
		}//众数;
		int SprD() {
			return Max()-Min();
		}//极差;
		double SqrD() {
			int avr = Averange();
			long long sqr = 0;
			for(int i = 1;i <= maxn;++i) 
				sqr += num[i]*(i-avr)*(i-avr);
			double res = 1.0*sqr/sizev;
			return res;
		}//方差;
		double StdD() {
			return sqrt(SqrD());
		}//标准差;
		void merge(BIT_TREE x) {
			
		}
} bit;
void work() {
	int n;
	scanf("%d",&n);
	bit.init(the_size-10);
	for(int i = 1, opt, x;i <= n;++i) {
		scanf("%d %d",&opt,&x);
		switch(opt) {
			case 1 : 
				bit.Insert(x);
				break;
			case 2 : 
				bit.Delete(x);
				break;
			case 3 : 
				printf("%d\n",bit.Rank(x));
				break;
			case 4 : 
				printf("%d\n",bit.Number(x));
				break;
			case 5 :
				printf("%d\n",bit.Pre(x));
				break;
			case 6 :
				printf("%d\n",bit.Suc(x));
				break;
		}
	}
}
signed main() {
	work();
}

\(2022.06.16\)

2022.06.15
#include <stdio.h>
#include <string.h>
#include <cmath>
const int z = 65536;
struct BIT {
	int tree[z];
	int maxn;
	#define lowbit(x) (x&(-x))
	int query(int pos) {
		int res = 0;
		for(pos;pos > 0;pos -= lowbit(pos)) 
			res += tree[pos];
		return res;
	}
	int query(int l,int r) {
		return query(r)-query(l-1);
	}
	void modify(int pos,int val) {
		for(pos;pos <= maxn;pos += lowbit(pos)) 
			tree[pos] += val;
	}
	void init(int a[],int size) {
		for(int i = 1, j;i <= size;++i) {
			tree[i] += a[i];
			j = i+lowbit(i);
			if(j <= size) 
				tree[j] += tree[i];
		}
	}
	#undef lowbit
	void init(int size) {
		memset(tree,0,(maxn+1)*sizeof(int));
		maxn = size;
	}
} bit;
int n, m;
int num[z];
void work_1() {
	scanf("%d %d",&n,&m);
	bit.init(n);
	for(int i = 1;i <= n;++i) 
		scanf("%d",&num[i]);
	bit.init(num,n);
	//for(int i = 1, tmp;i <= n;++i) {
	//	scanf("%d",&tmp);
	//	bit.modify(i,tmp);
	//}
	for(int i = 1, opt, x, y;i <= m;++i) {
		scanf("%d",&opt);
		if(opt) {
			scanf("%d %d",&x,&y);
			bit.modify(x,y);
		} else {
			scanf("%d %d",&x,&y);
			printf("%d\n",bit.query(x,y));
		}
	}
}//单点修改,区间查询(其实也是单点查询);
void work_2() {
	scanf("%d %d",&n,&m);
	bit.init(n);
	for(int i = 1, tmp, last = 0;i <= n;++i) {
		scanf("%d",&tmp);
		bit.modify(i,tmp-last);
		last = tmp;
	}
	for(int i = 1, opt, x, y, k;i <= m;++i) {
		scanf("%d %d",&opt,&x);
		if(opt) {
			scanf("%d %d",&y,&k);
			bit.modify(x,k);
			bit.modify(y+1,-k);
		} else {
			printf("%d\n",bit.query(x));
		}
	}
}//区间修改,单点查询;
struct RANGE_BIT {
	int treea[z];
	int treeb[z];
	int maxn;
	#define lowbit(x) (x&(-x))
	int query(int which[],int pos) {
		int res = 0;
		for(pos;pos > 0;pos -= lowbit(pos)) 
			res += which[pos];
		return res;
	}
	int query(int l,int r) {
		return (r+1)*query(treea,r)-l*query(treea,l-1)-
				(query(treeb,r)-query(treeb,l-1));
	}
	void modify(int pos,int val) {
		int vp = pos*val;
		for(pos;pos <= maxn;pos += lowbit(pos)) 
			treea[pos] += val, treeb[pos] += vp;
	}
	void modify(int l,int r,int val) {
		modify(l,val);
		modify(r+1,-val);
	}
	#undef lowbit
	void init(int size) {
		memset(treea,0,(maxn+1)*sizeof(int));
		memset(treeb,0,(maxn+1)*sizeof(int));
		maxn = size;
	}
} rbit;
void work_3() {
	scanf("%d %d",&n,&m);
	rbit.init(n);
	for(int i = 1, tmp;i <= n;++i) {
		scanf("%d",&tmp);
		rbit.modify(i,i,tmp);
	}
	for(int i = 1, opt, x, y, k;i <= m;++i) {
		scanf("%d %d %d",&opt,&x,&y);
		if(opt) {
			scanf("%d",&k);
			rbit.modify(x,y,k);
		} else {
			printf("%d\n",rbit.query(x,y));
		}
	}
}//区间修改,区间查询;
struct VALUE_BIT {
	int tree[z];
	int maxn;
	void add(int v) {
		tree[v]++;
		return;
	}
	void minus(int v) {
		if(tree[v]) 
			tree[v]--;
		return;
	}
	int kth(int k) {
		int cnt = 0, res = 0;
		for(int i = log(maxn);~i;--i) {
			res += 1<<i;
			if(res >= maxn||cnt+tree[res] >= k) 
				res -= 1<<i;
			else 
				cnt += tree[res];
		}
		return res+1;
	}
	void init(int size) {
		memset(tree,0,(maxn+1)*sizeof(int));
		maxn = size;
	}
} vbit;
void work_4() {
	scanf("%d %d",&n,&m);
	vbit.init(n);
	for(int i = 1, opt, x;i <= m;++i) {
		scanf("%d %d",&opt,&x);
		if(opt == 1) {
			vbit.add(x);
		} else if(opt == 2) {
			vbit.minus(x);
		} else {
			printf("%d\n",vbit.kth(x));
		}
	}
}
signed main() {
	work_4();
	//to do;
}

\(2022.06.07:\text{重修树状数组}.\)

\(2022.06.15:O(n)\text{建树},kth\)

#include <bits/stdc++.h>;
using namespace std;
const int z = 1024;
int tree[z];
int lowbit(int &amp;x) {
	return x&amp;(-x);
}
int qsum(int x) {
	int s = 0;
	while(x &gt; 0) {
		s += tree[x];
		x -= lowbit(x);
	}
	return s;
}
void padd(int n,int x,int key) {
	while(x &lt;= n) {
		tree[x] += key;
		x += lowbit(x);
	}
	return;
}
void qrpa(int *data) {
	int datb[z];
	for(int i = 1;i &lt;= data[0];++i) {
		datb[i] = data[i]-data[i-1];
		tree[i] = tree[i-1]+datb[i];
	}
	int l, r, m, key;
	scanf("%d",&amp;m);
	for(int i = 1;i &lt;= m;++i) {
		scanf("%d %d",&amp;l,&amp;r,&amp;key);
		padd(data[0],l,key);
		padd(data[0],r+1,-key);
	}
	for(int i = 1;i &lt;= data[0];++i) 
		printf("%d\n",qsum(i));
}
int main() {
	//to do;
	return 0;
}

二维树状数组

const int N = 1024;
int tree[N][N];
int xupd = 128, yupd = 128;
void modify(int _x,int _y,int _val) {
	for(register int i = _x;i <= xupd;i += i&-i) 
		for(register int j = _y;j <= yupd;j += j&-j) 
			tree[i][j] += _val;
}
int query(int _x,int _y) {
	int _res = 0;
	for(;_x;_x &= x-1) 
		for(register int j = _y;j;j &= j-1) 
			_res += tree[i][j];
	return _res;
}
int query(int _x1,int _x2,int _y1,int _y2) {
	return query(_x2,_y2)-query(_x2,_y1-1)-query(_x1-1,_y2)+query(_x1-1,_y1-1);
}
posted @ 2022-02-11 18:02  bikuhiku  阅读(54)  评论(0编辑  收藏  举报