树状数组的建树 单点修改 单点查询 区间修改 区间查询

单点修改  单点查询   用普通数组就能写出来  

单点修改  区间查询   用线段树  树状数组;

区间修改  区间查询   用线段树  树状数组;

区间修改  单点查询   用线段树  树状数组;

 

建树  

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
struct node
{
    int l,r,w;
}tree[4*maxn+1];
void build(int l,int r,int k)
{
    tree[k].l=l; tree[k].r=r;
    if(l==r)  { cin>>tree[k].w; return ; }
    int mid=(l+r)/2;
    build(l,mid,2*k);
    build(mid+1,r,2*k+1);
    tree[k].w=tree[2*k].w+tree[2*k+1].w;
}
int main()
{
    build(1,8,1);
}
建树

单点查询

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
struct node
{
    int l,r,w;
}tree[4*maxn+1];
void build(int l,int r,int k)
{
    tree[k].l=l; tree[k].r=r;
    if(l==r)  { cin>>tree[k].w; cout<<l<<"--"<<tree[k].w<<endl; return ; }
    int mid=(l+r)/2;
    build(l,mid,2*k);
    build(mid+1,r,2*k+1);
    tree[k].w=tree[2*k].w+tree[2*k+1].w;
}
int ask(int x,int k)// dian dian cha xun;
{
   if(tree[k].l==tree[k].r) {return tree[k].w; }
   int mid=(tree[k].l+tree[k].r)/2;
   if(x<=mid) return ask(x,2*k);
   else       return ask(x,2*k+1);

}
int main()
{
    build(1,8,1);
    //for(int i=1;i<=8;i++) cout<<"=="<<ask(i)<<endl;
    cout<<ask(1,1)<<endl;
    cout<<ask(7,1)<<endl;
}
单点查询

 单点修改(改变一个节点的值,在一个节点上加值)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
struct node
{
    int l,r,w;
}tree[4*maxn+1];
void build(int l,int r,int k)
{
    tree[k].l=l; tree[k].r=r;
    if(l==r)  { cin>>tree[k].w; /*cout<<l<<"--"<<tree[k].w<<endl;*/ return ; }
    int mid=(l+r)/2;
    build(l,mid,2*k);
    build(mid+1,r,2*k+1);
    tree[k].w=tree[2*k].w+tree[2*k+1].w;
}
int ask(int x,int k)// dian dian cha xun;
{
   if(tree[k].l==tree[k].r) {return tree[k].w; }
   int mid=(tree[k].l+tree[k].r)/2;
   if(x<=mid) return ask(x,2*k);
   else       return ask(x,2*k+1);

}
void change(int x,int y,int k)// 将 节点 x  修改为y
{
    if(tree[k].l==tree[k].r){ tree[k].w=y; return;  }
    int mid=(tree[k].l+tree[k].r)/2;
    if(x<=mid) return change(x,y,2*k);
    else       return change(x,y,2*k+1);
}
void changeodd(int x,int y,int k)// 将 节点 x  修改为y
{
    if(tree[k].l==tree[k].r){ tree[k].w+=y; return;  }
    int mid=(tree[k].l+tree[k].r)/2;
    //cout<<"  "<<tree[k].l<<"  "<<tree[k].r<<endl; cout<<mid<<endl;
    if(x<=mid) return changeodd(x,y,2*k);
    else       return changeodd(x,y,2*k+1);
}
int main()
{
    build(1,8,1);
    change(1,10,1);
    changeodd(1,10,1);
    cout<<ask(1,1)<<endl;
    cout<<ask(7,1)<<endl;
}
单点查询

 

 

模板  没有区间修改下的区间查询 和单点查询 。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
struct node
{
int l,r,w;
}tree[4*maxn+1];
void build(int l,int r,int k)
{
tree[k].l=l; tree[k].r=r;
if(l==r) { cin>>tree[k].w; /*cout<<l<<"--"<<tree[k].w<<endl;*/ return ; }
int mid=(l+r)/2;
build(l,mid,2*k);
build(mid+1,r,2*k+1);
tree[k].w=tree[2*k].w+tree[2*k+1].w;
}
int ask(int x,int k)// dian dian cha xun;
{
if(tree[k].l==tree[k].r) {return tree[k].w; }
int mid=(tree[k].l+tree[k].r)/2;
if(x<=mid) return ask(x,2*k);
else return ask(x,2*k+1);

}
void change(int x,int y,int k)// 将节点x修改为y
{
if(tree[k].l==tree[k].r){ tree[k].w=y; return; }
int mid=(tree[k].l+tree[k].r)/2;
if(x<=mid) change(x,y,2*k);
else change(x,y,2*k+1);
tree[k].w=tree[2*k].w+tree[2*k+1].w;
}
void changeodd(int x,int y,int k)// 将节点 x 上加y
{
if(tree[k].l==tree[k].r){ tree[k].w+=y; return; }
int mid=(tree[k].l+tree[k].r)/2;
//cout<<" "<<tree[k].l<<" "<<tree[k].r<<endl; cout<<mid<<endl;
if(x<=mid) changeodd(x,y,2*k);
else changeodd(x,y,2*k+1);
tree[k].w=tree[2*k].w+tree[2*k+1].w;
}
int query(int x,int y,int k) // 区间查询
{
int num=0;
if(tree[k].l==x && tree[k].r==y)
{
num+=tree[k].w; ; return num;
}
int mid=(tree[k].l+tree[k].r)/2;
if(x>=mid+1) num+=query(x,y,2*k+1);
else if(y<=mid) num+=query(x,y,2*k);
else num+=query(x,mid,2*k)+query(mid+1,y,2*k+1);

return num;
}int main()

{
build(1,8,1);
for(int i=1;i<=8;i++) {cout<<ask(1,1)<<" "; } cout<<endl;
cout<<query(1,7,1)<<endl;;
}

 区间修改(lazy标记)

 

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e5+10;
struct NODE
{
int l,r,w,f; // f 为lazy标记
}tree[4*maxn+10];
void build(int p,int q,int k)
{
tree[k].l=p; tree[k].r=q;
if(tree[k].l==tree[k].r) { cin>>tree[k].w;/* cout<<"==="<<tree[k].w<<endl;*/ return ; }
int mid=( tree[k].l+tree[k].r )/2;
build(p,mid,2*k);
build(mid+1,q,2*k+1);
tree[k].w=tree[2*k].w+tree[2*k+1].w;
}
void down(int k) // (lazy 标记) (××××) (important)
{
tree[2*k].f+=tree[k].f;
tree[2*k+1].f+=tree[k].f;
tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
tree[k].f=0;
}
void change_interval(int a,int b,int x,int k) // 区间修改 区间加值;
{
if(tree[k].l>=a && tree[k].r<=b )
{
tree[k].w+=(tree[k].r-tree[k].l+1)*x;
tree[k].f+=x;
return;
}
if(tree[k].f) down(k);
int mid=(tree[k].l+tree[k].r)/2;
if(b<=mid) change_interval(a,b,x,2*k);
else if(a>=mid+1) change_interval(a,b,x,2*k+1);
else change_interval(a,mid,x,2*k),change_interval(mid+1,b,x,2*k+1);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
void change_point(int x,int k)
{
if(tree[k].l==tree[k].r) { tree[k].w+=x; return; }
if(tree[k].f) down(k);
int mid=(tree[k].l+tree[k].r)/2;
if(x<=mid) change_point(x,2*k);
else change_point(x,2*k+1);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
int ask_interval(int a,int b,int k) // 区间查询
{
int num=0;

if(tree[k].l>=a&&tree[k].r<=b)
{
num+=tree[k].w;
return num;
}
if(tree[k].f) down(k);
int mid=( tree[k].l+tree[k].r)/2;
if(b<=mid) num+=ask_interval(a,b,2*k);
else if(a>=mid+1) num+=ask_interval(a,b,2*k+1);
else num+=ask_interval(a,mid,2*k)+ask_interval(mid+1,b,2*k+1);
return num;
}
int ask_point(int x,int k) // 点查询
{
int num=0;
if(tree[k].l==tree[k].r) {return tree[k].w; }
if(tree[k].f) down(k);
int mid=(tree[k].l+tree[k].r)/2;
if(x<=mid) ask_point(x,2*k);
if(x>=mid+1) ask_point(x,2*k+1);
}
int32_t main()
{
}

 

转载于:https://www.cnblogs.com/Andromeda-Galaxy/p/9715315.html