ACM 線段樹

求給定區間中的最值問題。對於長度爲n的數列A,求數組A中下標在[i,j]裏的最小值。
注: 這裏下標從1開始
輸入:
第一行兩個整數n和q,分別表示數列的長度和詢問的次數。
接下來n行爲n個整數,表示數列A中的元素。
接下來q行中,每行有兩個整數,表示所詢問的區間[I, j]的兩個端點
輸出:
對每一個詢問,給出指定區間中的最小值
樣例輸入:
9 2
5 8 1 3 6 4 9 5 7
2 4
6 9
樣例輸出:
1
4

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <string>
#include <cstdio>
#include <limits>
#include <vector>
#include <iostream>
using namespace std;
const int inf = 1e9;
const int maxn = 1 << 9;
//存儲線段樹的全局數組 
int n, tree[2*maxn-1];
int a[] = {5, 8, 1, 3, 6, 4, 9, 5, 7};
//初始化 
void init(int n_){
    //爲了簡單起見,把元素的個數擴大到2的冪 
    n = 1;
    while(n < n_) n *= 2;//
    //初始化所有值 
    for(int i = 0; i <= 2*n-1; i++){
        tree[i] = inf;
    }
}

void build(int node, int l, int r){
    if(l == r) tree[node] = a[l];
    else{
        build(node*2, l, (l+r)/2);
        build(node*2+1, (l+r)/2+1, r);
        if(tree[node*2] < tree[node*2+1]){
            tree[node] = tree[node*2];
        }else{
            tree[node] = tree[node*2+1];
        }
    }
}
// 把第k個值(0-indexed)更新爲val 
void update(int k, int val){
    //葉子節點 
    k += n;
    tree[k] = val;
    //向上更新
    while(k > 0){
        k = k / 2;
        tree[k] = min(tree[k*2], tree[k*2+1]);
    } 
}
//求[l, r]的最小值 
//後面的參數是爲了計算起來方便而傳入的 
//node是節點的編號,begin, end表示這個節點對應的是[begin, end]區間 
//在外部調用時,用query(1, 0, n-1, l, r )
int query(int node, int begin, int end, int l, int r){
    //如果[a, b)和[l, r)不相交, 則返回inf
    if(end < l || r < begin) return inf;
    // 如果[a, b)完全包含[l, r),則返回當前節點的值
    if(l <= begin && r >= end) return tree[node];
    else{
        //否則返回兩個兒子中值的較小者
        int vl = query(node*2, begin, (begin+end)/2, l, r);
        int vr = query(node*2+1, (begin+end)/2+1, end, l, r);
        return min(vl, vr); 
    }
} 

int main()
{
    int _n = 9, q = 2;
    init(_n);
    build(1, 0, n-1);
    //update(2,10);
    //update(8,10);
    int _min1 = query(1, 0, n-1, 1, 3);
    int _min2 = query(1, 0, n-1, 5, 8);
    cout << _min1 << endl;
    cout << _min2 << endl;

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章