线段树
推荐看视频理解:https://www.bilibili.com/video/av47331849
数组a及其组成的线段树:见图
代码:
#include <iostream>
#include <stdio.h>
using namespace std;
int a[1000] = {1,3,5,7,9,11};
int tree[4000] = {0};
int n = 6;
void built_tree( int node, int left, int right ) // 建树,node->树的编号,left,right->树的边界
{
if ( left==right ) {
tree[node] = a[left];
return ;
}
int mid = (left+right)/2;
int node_left = node*2+1;
int node_right = node*2+2;
built_tree(node_left,left,mid);
built_tree(node_right,mid+1,right);
tree[node] = tree[node_left] + tree[node_right];
}
void update( int node, int left, int right, int idx, int val ) // 将中的idx号的值变为val
{
if ( left==right ) {
a[idx] = val;
tree[node] = val;
return ;
}
int mid = (left+right)/2;
int node_left = node*2+1;
int node_right = node*2+2;
if ( idx>=left && idx<=mid ) {
update(node_left,left,mid,idx,val);
}
else {
update(node_right,mid+1,right,idx,val);
}
tree[node] = tree[node_left] + tree[node_right];
}
int query( int node, int left, int right, int L, int R ) // 询问L到R的值
{
printf("left = %d right = %d\n",left,right);
if ( R<left || L>right ) {
return 0;
}
else if ( left>=L && right<=R ) {
return tree[node];
}
else if ( left==right ) {
return tree[node];
}
int mid = (left+right)/2;
int node_left = node*2+1;
int node_right = node*2+2;
int sum_left = query(node_left,left,mid,L,R);
int sum_right = query(node_right,mid+1,right,L,R);
return sum_left + sum_right;
}
int main()
{
built_tree(0,0,n-1);
for ( int i; i<=14; i++ ) {
printf("tree[%d] = %d\n",i,tree[i]);
}
printf("\n");
update(0,0,n-1,4,6);
for ( int i; i<=14; i++ ) {
printf("tree[%d] = %d\n",i,tree[i]);
}
printf("\n");
int sum = query(0,0,n-1,2,5);
printf("sum[2,5] = %d\n",sum);
return 0;
}
建树的结果:
update a[4] = 6 的结果:
询问2 5 的结果: