单点修改 单点查询 用普通数组就能写出来
单点修改 区间查询 用线段树 树状数组;
区间修改 区间查询 用线段树 树状数组;
区间修改 单点查询 用线段树 树状数组;
建树
#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()
{
}