学的太少了,就先写这一点。
如果bug 欢迎指出!
(一 ) 一维的树状数组
1 > 单点加减,区间求和查询。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define fread() freopen("in.txt","r",stdin)
#define fwrite() freopen("out.txt","w",stdout)
#define CLOSE() ios_base::sync_with_stdio(false)
const int MAXN = 15000+10;
const int MAXM = 1e6+10;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
struct BIT{
int n;
int c[MAXN];
inline int lowbit(int x) { return x&(-x);}
void add(int x,int val){
for(int i=x;i<=n;i+=lowbit(i))
c[i]+=val;
}
int sum(int x){
int ans=0;
for(int i=x;i>0;i-=lowbit(i))
ans+=c[i];
return ans;
}
}bit;
int main(){
memset(bit.c,0,sizeof(bit.c)); // 赋初值
int q;scanf("%d%d",&bit.n,&q);
while(q--){
puts("===");
char op[2];
scanf("%s",op);
if(op[0]=='C') {
int x,y,val;scanf("%d%d",&x,&val);
bit.add(x,val);
}else {
int x;scanf("%d",&x);
printf("%d\n",bit.sum(x));
}
}
return 0;
}
2 > 区间更新,单点查询
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define fread() freopen("in.txt","r",stdin)
#define fwrite() freopen("out.txt","w",stdout)
#define CLOSE() ios_base::sync_with_stdio(false)
const int MAXN = 15000+10;
const int MAXM = 1e6+10;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
struct BIT{
int n;
int c[MAXN];
inline int lowbit(int x) { return x&(-x);}
void add(int x,int val){
for(int i=x;i<=n;i+=lowbit(i))
c[i]+=val;
}
int sum(int x){
int ans=0;
for(int i=x;i>0;i-=lowbit(i))
ans+=c[i];
return ans;
}
}bit;
int main(){
CLOSE();
// fread();
// fwrite();
memset(bit.c,0,sizeof(bit.c)); // 清空
int q;scanf("%d%d",&bit.n,&q);
while(q--){
char op[2];
scanf("%s",op);
if(op[0]=='C') { // 区间更新,单点询问
int x,y,val;scanf("%d%d%d",&x,&y,&val);
bit.add(x,val);
bit.add(y+1,-val); //
}else {
int x;scanf("%d",&x);
printf("%d\n",bit.sum(x));
}
}
return 0;
}
(二 )二维的树状数组
实现的功能和一维的一样,不过就是从线换成了平面 。
矩形区域 用左下坐标和右上坐标来表示。
1 > 更新一个点的值,查询平面内一个矩形区域所有点的和 。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define fread() freopen("in.txt","r",stdin)
#define fwrite() freopen("out.txt","w",stdout)
#define CLOSE() ios_base::sync_with_stdio(false)
const int MAXN = 15000+10;
const int MAXM = 1e6+10;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
struct BIT{
int nx,ny;
int c[MAXN][MAXN];
inline int lowbit(int x){ return x&(-x) ; }
void add(int x,int y,LL val){
for(int i=x;i<=nx;i+=lowbit(i))
for(int j=y;j<=ny;j+=lowbit(j))
c[i][j]+=val;
}
int sum(int x,int y){
int ans=0;
for(int i=x;i>0;i-=lowbit(i))
for(int j=y;j>0;j-=lowbit(j))
ans+=c[i][j];
return ans;
}
} bit;
int main(){
CLOSE();
// fread();
// fwrite();
int n; int q;
scanf("%d%d",&n,&q); bit.nx=bit.ny=n;
memset(bit.c,0,sizeof(bit.c));
int x1,y1,x2,y2,val; char op[2];
while(q--){
scanf("%s",op);
if(op[0]=='Q') {
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x1--;y1--;
printf("%d\n",bit.sum(x2,y2)+bit.sum(x1,y1)-bit.sum(x1,y2)-bit.sum(x2,y1));
}else {
scanf("%d%d%d",&x1,&y1,&val);
bit.add(x1,y1,val);
}
}
return 0;
}
2 > 平面内一个矩形区域所有值的加减,查询单点的值。
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>pii;
#define first fi
#define second se
#define LL long long
#define fread() freopen("in.txt","r",stdin)
#define fwrite() freopen("out.txt","w",stdout)
#define CLOSE() ios_base::sync_with_stdio(false)
const int MAXN = 2500+10;
const int MAXM = 1e6;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const int seed = 2333 ;
struct BIT{
int nx,ny;
int c[MAXN][MAXN];
inline int lowbit(int x){ return x&(-x) ; }
void add(int x,int y,LL val){
for(int i=x;i<=nx;i+=lowbit(i))
for(int j=y;j<=ny;j+=lowbit(j))
c[i][j]+=val;
}
int sum(int x,int y){
int ans=0;
for(int i=x;i>0;i-=lowbit(i))
for(int j=y;j>0;j-=lowbit(j))
ans+=c[i][j];
return ans;
}
} bit;
int main(){
CLOSE();
// fread();
// fwrite();
int q,n;scanf("%d%d",&q,&n); bit.nx=bit.ny=n;
memset(bit.c,0,sizeof(bit.c));
int x1,y1,x2,y2,val; char op[2];
while(q--){
scanf("%s",op);
if(op[0]=='C') {
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&val);
x2++;y2++;
bit.add(x1,y1,val);
bit.add(x1,y2,-val);
bit.add(x2,y1,-val);
bit.add(x2,y2,val); // 多减的一部分加回来
}else {
scanf("%d%d",&x1,&y1);
printf("%d\n",bit.sum(x1,y1));
}
}
return 0;
}