参考:挑战程序设计竞赛·[第二版] 169页
线段树是一颗区间树,也是一颗满二叉树
实现代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> using namespace std; const int MAXN=1<<17; int dat[2*MAXN-1]; int n; void init(int n_){ n=1; while(n<n_){ n*=2; } fill(dat,dat+2*n-1,INT_MAX); } //将第k个值(0-indexed)更新为val void update(int k,int val){ //这是线段树的最后一层的下标 k+=n-1; dat[k]=val; while(k>0){ k=(k-1)/2; dat[k]=min(dat[k*2+1],dat[k*2+2]); } } //求[a,b)范围内的最小值 //初始化情况query(a,b,0,0,n) int query(int a,int b,int k,int l,int r){ //[a,b)和[l,r)没有相交的情况。 if(a>=r||b<=l) return INT_MAX; //[a,b)包含[l,r) if(a<=l&&b>=r) return dat[k]; else{ int vl=query(a,b,2*k+1,l,(l+r)/2); int vr=query(a,b,2*k+2,(l+r)/2,r); return min(vl,vr); } }