ABC359

拍手称快發表於2024-06-25

ABC359

E

題目很簡單,大概就是要求陣列中一個數的左側第一個比它大的值。這裡就需要用單調棧來實現了。

單調棧

單調棧就是透過棧的性質,來實現快速查詢一個數的左側第一個比他大的數。

  • 過程
    建立一個棧,判斷棧頂元素是否小於當前元素,如果小於則將棧頂元素彈出直到棧頂元素大於當前元素,最後將當前元素壓入棧。
  • 原理
    因為對所有的值的處理只會有判斷和彈出,元素不會被重複遍歷。所以可以實現O(n)的時間複雜度。
    程式碼實現
void solve()
{   
    i64 n;
    std::cin>>n;
    std::vector<i64>a(n+1),ans(n+1);
    for(int i=0;i<n;i++){
        std::cin>>a[i];
    }
    std::stack<i64>st;
    ans[0]=a[0];
    i64 maxn=a[0];
    i64 num=0;
    st.push(0);
    for(int i=1;i<n;i++){
       
       while(!st.empty()&&a[st.top()]<a[i]){//這裡就是單調棧的實現,由於題目需求,這裡棧壓入的是陣列元素的下標
        st.pop();
       }
       if(!st.empty()){
            ans[i]=(i-st.top())*a[i]+ans[st.top()];
       }else{
            ans[i]=(i+1)*a[i];
       }
       st.push(i);
    }
    for(int i=0;i<n;i++){
        std::cout<<ans[i]+1<<" ";
    }
    std::cout<<"\n";
}

相關文章