建树
void build(int o,int l,int r) //o:当前建立的节点 l:左端点 r:右端点 { if(l == r) //建立叶子信息 st[o] = a[l]; else { int m = l + ((r-l) >> 1); // m 为中间点,左儿子结点为 [l,m] ,右儿子结点为 [m+1,r]; build(o << 1,l,m); //构建左儿子结点 build((o<<1)|1,m+1,r); //构建右儿子结点 st[o] = max(st[o << 1],st[(o<<1)|1]); //递归返回时用儿子结点更新父节点,此处可进行更新最大值、最小值、区间和等操作 } } build(1, 1, n);//主函数里的语句
单点修改
void update(int o,int l,int r,int ind,int ans) //o、l、r为当前更新到的结点、左右端点,ind为需要修改的叶子结点左端点,ans为需要修改成的值; { if(l == r) //若当前更新点的左右端点相等即到叶子结点时,直接更新信息并返回 { st[o] = ans; return ; } int m = l + ((r-l) >> 1); if(ind <= m) update(o << 1,l,m,ind,ans); else update((o<<1)|1,m+1,r,ind,ans); st[o] = max(st[o<<1],st[(o<<1)|1]); //递归回之后用儿子结点更新父节点(此处是区间最大值)也可以是最小值或者是区间和 } update(1, 1, n, a, b);//在主函数里的语句
区间查询
int query(int o,int l,int r,int ql,int qr) //ql、qr为需要查询的区间左右端点 { if(ql > r || qr < l) //若当前结点和需要查找的区间不相交,则返回一个对于区间查询无关的值(如求和时返回0,求最大值时返回-1等) return -1; if(ql <=l && qr >=r) //若当前结点的区间被需要查询的区间覆盖,则返回当前结点的信息 return st[o]; int m = l + ((r-l) >> 1); int p1 = query(o<<1,l,m,ql,qr); //p1为查询左儿子结点得到的信息,p2为查询右儿子结点得到的信息 int p2 = query((o<<1)|1,m+1,r,ql,qr); return max(p1,p2); //综合两个儿子结点的信息并返回 } query(1, 1, n, a, b)//主函数里的查询语句
原文地址:https://www.cnblogs.com/smallhester/p/10498731.html
时间: 2024-10-17 10:21:23