【模板】树状数组
有限值域平衡树
#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 &x) {
return x&(-x);
}
int qsum(int x) {
int s = 0;
while(x > 0) {
s += tree[x];
x -= lowbit(x);
}
return s;
}
void padd(int n,int x,int key) {
while(x <= n) {
tree[x] += key;
x += lowbit(x);
}
return;
}
void qrpa(int *data) {
int datb[z];
for(int i = 1;i <= data[0];++i) {
datb[i] = data[i]-data[i-1];
tree[i] = tree[i-1]+datb[i];
}
int l, r, m, key;
scanf("%d",&m);
for(int i = 1;i <= m;++i) {
scanf("%d %d",&l,&r,&key);
padd(data[0],l,key);
padd(data[0],r+1,-key);
}
for(int i = 1;i <= 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);
}