将最近学习的好好总结一下,这些代码都是艾教的代码,感觉风格很好。
树状数组的基本应用:1.更新单点查询区间2.更新区间查询单点3.二维树状数组的应用
更新区间的方法是:在[l,r]上面增加x,然后查询某一位,只需要在l位上面增加x,在r+1的位置上面增加-x。二维树状数组也可以这样做。
const int maxn = 1e3;
int arr[maxn][maxn];
int N;
int lowbit(int i) {
return i & -i;
}
void add(int x, int t)
{
for(int i = x; i <= N; i += lowbit(i)) {
for(int j =x ; j <= N; j += lowbit(i)) {
arr[i][j] += t;
}
}
}
int sum(int x)
{
int sum = 0;
for(int i = x; i > 0; i -= lowbit(i)) {
for(int j = x; j > 0; j -= lowbit(j)) {
sum += arr[i][j];
}
}
return sum;
}
线段树的应用:1.更新单点查询区间2.更新区间查询单点
#include <iostream>
#include <cstdio>
#define N 100005
#define lson (id<<1)
#define rson ((id<<1)|1)
#define mid ((l+r)>>1)
using namespace std;
struct nod{
int MAX;
}tree[N*5];
int n,q;
void push_up(int id)
{
tree[id].MAX=max(tree[lson].MAX,tree[rson].MAX);
return;
}
void build_tree(int id,int l,int r)
{
if (l==r)
{
scanf("%d",&tree[id].MAX);
return;
}
build_tree(lson,l,mid);
build_tree(rson,mid+1,r);
push_up(id);
return;
}
void ins(int id,int l,int r,int pos,int tt)
{
if (l==r)
{
tree[id].MAX+=tt;
return;
}
if (pos<=mid)
ins(lson,l,mid,pos,tt);
else
ins(rson,mid+1,r,pos,tt);
push_up(id);
return;
}
int query(int id,int l,int r,int ql,int qr)
{
if (ql<=l && r<=qr)
{
return tree[id].MAX;
}
int zuida=-99999999;
if (ql<=mid)
zuida=max(zuida,query(lson,l,mid,ql,qr));
if (mid+1<=qr)
zuida=max(zuida,query(rson,mid+1,r,ql,qr));
return zuida;
}
int main()
{
while (cin>>n>>q)
{
build_tree(1,1,n);
while (q--)
{
int f,x,y;
cin>>f>>x>>y;
if (f==1)
{
ins(1,1,n,x,y);
}
else
{
cout<<query(1,1,n,x,y)<<endl;
}
}
}
}
#include <iostream>
#include <cstdio>
#define N 10000005
#define lson (id<<1)
#define rson ((id<<1)|1)
#define mid ((l+r)>>1)
using namespace std;
struct nod{
int sum,lazy;
}tree[N*5];
int n,q;
void push_up(int id)
{
tree[id].sum=tree[lson].sum+tree[rson].sum;
return;
}
void build_tree(int id,int l,int r)
{
if (l==r)
{
scanf("%d",&tree[id].sum);
tree[id].lazy=0;
return;
}
build_tree(lson,l,mid);
build_tree(rson,mid+1,r);
push_up(id);
tree[id].lazy=0;
return;
}
void push_down(int id,int l,int r)
{
tree[lson].sum+=(mid-l+1)*tree[id].lazy;
tree[lson].lazy+=tree[id].lazy;
tree[rson].sum+=(r-mid)*tree[id].lazy;
tree[rson].lazy+=tree[id].lazy;
tree[id].lazy=0;
return;
}
void ins(int id,int l,int r,int ql,int qr,int tt)
{
if (ql<=l && r<=qr)
{
tree[id].sum+=(r-l+1)*tt;
tree[id].lazy+=tt;
return;
}
if (tree[id].lazy) push_down(id,l,r);
if (ql<=mid)
ins(lson,l,mid,ql,qr,tt);
if (mid+1<=qr)
ins(rson,mid+1,r,ql,qr,tt);
push_up(id);
return;
}
int query(int id,int l,int r,int ql,int qr)
{
if (ql<=l && r<=qr)
{
return tree[id].sum;
}
if (tree[id].lazy)
push_down(id,l,r);
int sum=0;
if (ql<=mid)
sum+=query(lson,l,mid,ql,qr);
if (mid+1<=qr)
sum+=query(rson,mid+1,r,ql,qr);
return sum;
}
int main()
{
while (cin>>n>>q)
{
build_tree(1,1,n);
while (q--)
{
int f,x,y;
cin>>f>>x>>y;
if (f==1)
{
int tt;
cin>>tt;
ins(1,1,n,x,y,tt);
}
else
{
cout<<query(1,1,n,x,y)<<endl;
}
}
}
}