线段树

参考:挑战程序设计竞赛·[第二版] 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);
    }
}
自己选的路,跪着也要把它走完------ACM坑
原文地址:https://www.cnblogs.com/IKnowYou0/p/6391107.html