const int max_n=1<<17; //存储线段树的全局数组 int n,dat[2*MAX_n-1]; //初始化 void init(int n_){ //把元素扩大到2的幂 n=1; while(n<n_)n*=2; //把所有值设为INT_MAX for(itn i=0;i<2*n-1;i++) dat[i]=INT_MAX; } //把第k个值(0-indexed)更新为a void update(int k,int a){ //叶子节点 k+=n-1;//叶子为n的完全树有n-1个非叶子节点 dat[k]=a; // 向上跟新 while(k>0){ k=(k-1)/2; dat[k]=min(dat[k*2+1],dat[k*2+2]);//注意是下标是从0开始,所以有些变化 } } //求[a,b)的最小值 //后面的参数为了方便计算传入,原则上可以计算出 //k时节点编号,l,r表示[l,r)区间 //外部调用时用query(a,b,0,0,n) int query(int a,int b,int k,int l,int ,r){ //如果[a,b)和[l.r)不相交,则返回INT_MAX if(r<=a||b<=1) return INT_MAX; //如果包含返回当前节点的值 if(a<=l&&r<=b) return dat[k]; else { int v1=query(a,b,k*2+1,l,(l+r)/2); int v2=query(a,b,k*2+2,(l+r)/2,r); return min(v1,v2); } }