第一步先建造树
void build(int node,int L,int R) { if(L==R) tree[node]=a[L]; else { int mid=(L+R)/2; build(node*2,L,mid);//建立左子树 build(node*2+1,mid+1,R);//建立右子树 tree[node]=tree[node*2]+tree[node*2+1]; } }1.单点修改,区间查询。
void update(int node,int L,int R,int x,int y)//修改 { if(L==R) tree[node]+=y; else { int mid=(L+R)/2; if(x<=mid) update(node*2,L,mid,x,y); else update(node*2+1,mid+1,R,x,y); tree[node]=tree[node*2]+tree[node*2+1]; } } void query(int node,int L,int R,int x,int y)//查询 { if(x<=L&&y>=R) sum+=tree[node]; else { int mid=(L+R)/2; if(x<=mid) query(node*2,L,mid,x,y); else query(node*2+1,mid+1,R,x,y); } }2.区间修改,单点查询 区间修改要用到懒惰标记,lazy数组。
void lazytree(int node,int l)//懒惰标记 { if(lazy[node]) { lazy[node*2]+=lazy[node]; lazy[node*2+1]+=lazy[node]; tree[node*2]+=lazy[node]*(l-l/2); tree[node*2+1]+=lazy[node]*(l/2); lazy[node]=0; } } void update(int node,int L,int R,int x,int y,int z)//修改 { if(x<=L&&y>=R) { tree[node]+=(R-L+1)*z; lazy[node]+=z; } else { lazytree(node,R-L+1); int mid=(L+R)/2; if(x<=mid) update(node*2,L,mid,x,y,z); if(y>mid) update(node*2+1,mid+1,R,x,y,z); tree[node]=tree[node*2]+tree[node*2+1]; } } void query(int node,int L,int R,int x)//查询 { if(L==R) printf("%d\n",tree[node]); else { lazytree(node,R-L+1); int mid=(L+R)/2; if(x<=mid) query(node*2,L,mid,x); else query(node*2+1,mid+1,R,x); } }3.区间修改区间查询
void lazytree(int node,int l) { if(lazy[node]) { lazy[node*2]+=lazy[node]; lazy[node*2+1]+=lazy[node]; tree[node*2]+=lazy[node]*(l-l/2); tree[node*2+1]+=lazy[node]*(l/2); lazy[node]=0; } } void update(int node,int L,int R,int x,int y,int z)//修改 { if(x<=L&&y>=R) { tree[node]+=(R-L+1)*z; lazy[node]+=z; } else { lazytree(node,R-L+1); int mid=(L+R)/2; if(x<=mid) update(node*2,L,mid,x,y,z); if(y>mid) update(node*2+1,mid+1,R,x,y,z); tree[node]=tree[node*2]+tree[node*2+1]; } } void query(int node,int L,int R,int x,int y)//查询 { if(x<=L&&y>=R) sum+=tree[node]; else { lazytree(node,R-L+1); int mid=(L+R)/2; if(x<=mid) query(node*2,L,mid,x,y); if(y>mid) query(node*2+1,mid+1,R,x,y); } }