c_cpp 线段树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 线段树相关的知识,希望对你有一定的参考价值。

#include<bits/stdc++.h>
using namespace std;

// https://www.youtube.com/watch?v=FR5d4V7Z9SE&t=0s&list=WL&index=24

void buildTree(vector<int> &st,vector<int> a,int index,int start,int end){
    // Base case #1
    if(start>end){
        return;
    }
    // Base case #2
    if(start == end){
        st[index]=a[start];
        return;
    }
    int mid=start+((end-start)/2);
    int lChild=(2*index)+1;
    int rChild=(2*index)+2;
    buildTree(st,a,lChild,start,mid);
    buildTree(st,a,rChild,mid+1,end);
    st[index]=min(st[lChild],st[rChild]); // range min query
}
int RangeMin(vector<int> st,int index,int start,int end,int ql, int qr){
    // No Overlap
    if( ( /* ql<start && */ qr<start) || (ql>end /* && qr>end */) ){
        return INT_MAX; // range min query
    }
    // Complete Overlap
    if(ql<=start && qr>=end){
        return st[index];
    }
    // Partial Overlap
    int mid=start+(end-start)/2;
    int lChildMin=RangeMin(st,(2*index)+1,start,mid,ql,qr);
    int rChildMin=RangeMin(st,(2*index)+2,mid+1,end,ql,qr);
    return min(lChildMin,rChildMin);
}
void UpdateNode(vector<int> &st,int index,int qindex,int val,int start,int end){
    // lies outside
    if(qindex<start || qindex>end){
        return;
    }
    // leaf node
    if(/* start==qindex && */ start==end){
        st[index]=val;
        return;
    }
    // lies b/w
    if(qindex>=start && qindex<=end){
        int mid=start+(end-start)/2;
        UpdateNode(st,(2*index)+1,qindex,val,start,mid);
        UpdateNode(st,(2*index)+2,qindex,val,mid+1,end);
        st[index]=min(st[(2*index)+1],st[(2*index)+2]);
    }
}
void UpdateRange(vector<int> st,int index,int start,int end,int rl,int rr,int inc){
    // No overlap
    if((/* rl<start &&  */ rr<start) || (rl>end && /* rr>end */)){
        return;
    }
    // Complete overlap
    if(rl<=start && rr>=end){
        st[index]+=inc; // increment
    }
    // Partial overlap
    int mid=start+(end-start)/2;
    UpdateRange(st,(2*index)+1,start,mid,rl,rr,inc);
    UpdateRange(st,(2*index)+2,mid+1,end,rl,rr,inc);
    st[index]=min(st[(2*index)+1],st[(2*index)+2]);
}

int main(){
    freopen("ip.txt","r",stdin);
    int n;
    cin>>n;
    vector<int> a(n);
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    vector<int> st(4*n,-999); // 4*n is max possible size
    buildTree(st,a,0,0,n-1);
    // for(int i=0;i<st.size();i++){
    //     cout<<st[i]<<" ";
    // }
    // cout<<endl;
    int q;
    cin>>q;
    while(q--){
        string c;
        cin>>c;
        if(c=="q"){
            int l,r;
            cin>>l>>r;
            cout<<RangeMin(st,0,0,n-1,l,r)<<endl;
        }else if(c=="un"){
            int qindex,val;
            cin>>qindex>>val;
            a[qindex]=val;
            UpdateNode(st,0,qindex,val,0,n-1);
        }
    }

    return 0;
}

以上是关于c_cpp 线段树的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp GFG如何检查两个给定的线段是否相交

错误记录加强版

权值线段树套序列线段树

一般线段树与权值线段树

详解权值线段树

权值线段树&&线段树合并