042.单调栈

单调栈

模板

luogu P5788

获取每个元素左右两侧第一个大于(小于)它的元素

const int N=1e5;
int a[N];
int top,st[N],L[N],R[N];
int n;
void init(){
    top=-1;
    for(int r=0;r<n;++r){
        while(top!=-1&&a[st[top]]<=a[r]){//第一个大于a[i]
            int i=st[top--];
            L[i]=top==-1?-1:st[top];
            R[i]=r;
        }
        st[++top]=r;
    }
    while(top!=-1){
        int i=st[top--];
        L[i]=top==-1?-1:st[top];
        R[i]=n;
    }
    //处理重复元素
    for(int i=n-2;i>=0;--i){
        if(R[i]!=n&&a[R[i]]==a[i]){
            R[i]=R[R[i]];
        }
    }
}

题单

luogu P1901

P1901
 void solve(){
    cin>>n;
    for(int i=0;i<n;++i)cin>>a[i]>>w[i];
    
    init();

    vector<int>cnt(n);
    for(int i=0;i<n;++i){
        int l=L[i];
        if(l!=-1)cnt[l]+=w[i];
        int r=R[i];
        if(r!=n)cnt[r]+=w[i];
    }

    int ans=-1;
    for(int x:cnt)if(x>ans)ans=x;

    cout<<ans;
}

luogu P8082

P8082
 void solve(){
    cin>>n>>k;
    string s;
    cin>>s;
    stack<char>st;
    for(char c:s){
        while(st.size()&&k&&c>st.top()){
            st.pop();
            k--;
        }
        st.push(c);
    }
    string ans="";
    while(st.size()){
        ans+=st.top();
        st.pop();
    }
    reverse(ans.begin(),ans.end());
    cout<<ans;
}

luogu P2886

P2886
 void solve(){
    cin>>n;
    for(int i=0;i<n;++i)cin>>a[i];

    init();

    long ans=0;
    for(int i=0;i<n;++i){
        ans+=R[i]-i-1;
    }
    cout<<ans;
}

luogu P2947

P2947
 void solve(){
    cin>>n;
    for(int i=0;i<n;++i)cin>>a[i];
    init();
    for(int i=0;i<n;++i){
        if(R[i]==n)cout<<0<<'\n';
        else cout<<R[i]+1<<'\n';
    }
}

luogu P8094

P8094
 void solve(){
    cin>>n;
    for(int i=0;i<n;++i)cin>>a[i];

    init();

    ll ans=0;
    for(int i=0;i<n;++i){
        if(L[i]!=-1)ans+=i-L[i]+1;
        if(R[i]!=n)ans+=R[i]-i+1;
    }
    cout<<ans;
}

luogu P13796

P13796
 typedef struct{
    ll mo;//分子
    ll de;//分母
}f;
ll gcd(ll a,ll b){
    if(a<0)a=-a;
    if(b<0)b=-b;
    ll t;
    while(b){
        t=b;
        b=a%b;
        a=t;
    }
    return a;
}
//化简
void simp(f* x){
    if(x->de<0){
        x->de=-x->de;
        x->mo=-x->mo;
    }
    ll cd=gcd(x->de,x->mo);
    x->de/=cd;
    x->mo/=cd;
}
void solve(){
    cin>>n;
    for(int i=0;i<n;++i)cin>>a[i];
    init();
    f ans;
    ans.de=1;
    ans.mo=0;
    for(int i=0;i<n;++i){
        int l=L[i],r=R[i];
        if(l!=-1&&i-l>1){
            f t;
            t.mo=a[i]-a[l+1];
            t.de=a[l]-a[l+1];
            t.mo+=t.de*(i-l-1);
            if(ans.mo*t.de<ans.de*t.mo)ans=t;
        }
        if(r!=n&&r-i>1){
            f t;
            t.mo=a[i]-a[r-1];
            t.de=a[r]-a[r-1];
            t.mo+=t.de*(r-i-1);
            if(ans.mo*t.de<ans.de*t.mo)ans=t;
        }
    }
    simp(&ans);
    if(ans.mo==0)cout<<0;
    else if(ans.de==1)cout<<ans.mo;
    else cout<<ans.mo<<'/'<<ans.de;
}

luogu P1823

P1823
 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=5e5+5;
int n;
int top=-1,st[N];
struct p{
    ll h;
    int cnt=1;
}P[N];
void solve(){
    cin>>n;
    for(int i=0;i<n;++i)cin>>P[i].h;
    ll ans=0;
    for(int i=0;i<n;++i){
        while(top!=-1&&P[st[top]].h<P[i].h){
            ans+=P[st[top]].cnt;
            top--;
        }
        if(top!=-1&&P[st[top]].h==P[i].h){
            ans+=P[st[top]].cnt;
            P[i].cnt+=P[st[top]].cnt;            
            top--;
        }
        if(top!=-1)ans++;
        st[++top]=i;
    }
    cout<<ans;
}
int main(void){
    cin.tie(0)->sync_with_stdio(0);
    int T=1;
    //cin>>T;
    while(T--)solve();
}

luogu P2422

P2422
 ll pre[N]={0};
void solve(){
    cin>>n;
    for(int i=0;i<n;++i)cin>>a[i],pre[i+1]=pre[i]+a[i];
    init();
    ll ans=0;
    for(int i=0;i<n;++i){
        int l=L[i],r=R[i];
        ll sum=pre[r]-pre[l+1];
        ans=max(ans,sum*a[i]);
    }
    cout<<ans;
}

luogu P3467

P3467
 void solve(){
    cin>>n;
    int w;
    for(int i=0;i<n;++i)cin>>w>>a[i];
    int ans=n;
    for(int i=0;i<n;++i){
        while(top!=-1&&a[st[top]]>=a[i]){
            if(a[st[top--]]==a[i])ans--;
        }
        st[++top]=i;
    }
    cout<<ans;
}

luogu P2659

P2659
void solve(){
 cin>>n;
    for(int i=0;i<n;++i)cin>>a[i];
    init();
    ll ans=0;
    for(int i=0;i<n;++i){
        int l=L[i],r=R[i];
        ans=max(ans,a[i]*(r-l-1));
    }
    cout<<ans;
}

luogu P3666

P3666
 void solve(){
    cin>>n;
    for(int i=1;i<=n;++i)cin>>a[i];
    top=-1;
    ll ans=0;
    for(int i=1;i<=n;++i){
        while(top!=-1&&a[st[top]]<=a[i]){
            ans^=st[top--];
        }
        st[++top]=i;
        ans^=i;
        cout<<ans<<'\n';
    }
}

leetcode 42

42
 class Solution {
public:
    int trap(vector<int>& height) {
        stack<int>st;
        int siz=height.size();
        int ans=0;
        for(int r=0;r<siz;++r){
            while(st.size()>1&&height[st.top()]<height[r]){
                int h=st.top();
                st.pop();
                int w=r-st.top()-1;
                ans+=w*(min(height[st.top()],height[r])-height[h]);
            }
            while(st.size()&&height[st.top()]<=height[r])st.pop();
            st.push(r);
        }
        return ans;
    }
};

leetcode 907

907
 const int P=1e9+7;
const int N=30005;
int L[N],R[N],st[N],top;
class Solution {
public:
    int sumSubarrayMins(vector<int>& arr) {
        int n=arr.size();
        top=-1;
        for(int r=0;r<n;++r){
            while(top!=-1&&arr[st[top]]>=arr[r]){
                int i=st[top--];
                L[i]=top==-1?-1:st[top];
                R[i]=r;
            }
            st[++top]=r;
        }
        while(top!=-1){
            int i=st[top--];
            L[i]=top==-1?-1:st[top];
            R[i]=n;
        }
        long ans=0;
        for(int i=0;i<n;++i){
            ans=(ans+(long)(i-L[i])*(R[i]-i)%P*arr[i])%P;
        }
        return (int)ans;
    }
};

leetcode 962

962
class Solution {
public:
    int maxWidthRamp(vector<int>& nums) {
        int n=nums.size();
        stack<int>st;
        st.push(0);
        for(int i=0;i<n-1;++i){
            if(nums[i]<nums[st.top()])st.push(i);
        }
        int ans=0;
        for(int i=n-1;i;i--){
            if(st.size()&&i<st.top())break;
            while(st.size()&&nums[st.top()]<=nums[i]){
                ans=max(ans,i-st.top());
                st.pop();
            }
        }
        return ans;
    }
};```
</details>

[leetcode 316](https://leetcode.cn/problems/remove-duplicate-letters/)

<details><summary> 316 </summary>

```cpp
 class Solution {
public:
    string removeDuplicateLetters(string s) {
        vector<int>cnt(26),vis(26);
        stack<char>st;
        for(char c:s)cnt[c-'a']++;
        for(char c:s){
            if(vis[c-'a']){
                cnt[c-'a']--;
                continue;
            }
            while(st.size()&&st.top()>c){
                if(cnt[st.top()-'a']){
                    vis[st.top()-'a']=0;
                    st.pop();
                }
                else{
                    break;
                }
            }
            st.push(c);
            cnt[c-'a']--;
            vis[c-'a']=1;
        }
        string ans="";
        while(st.size()){
            ans=st.top()+ans;
            st.pop();
        }
        return ans;
    }
};

leetcode 2289

2289
 class Solution {
public:
    int totalSteps(vector<int>& nums) {
        int n=nums.size();
        stack<pair<int,int>>st;
        int ans=0;
        for(int i=n-1;i>=0;--i){
            int cnt=0;
            while(st.size()&&st.top().first<nums[i]){
                cnt++;
                auto [_,t]=st.top();
                st.pop();
                cnt=max(cnt,t);
                ans=max(ans,cnt);
            }
            st.push({nums[i],cnt});
        }
        return ans;
    }
};

leetcode 84

84
 class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        heights.push_back(-1);
        int siz=heights.size();
        stack<int>st;
        st.push(-1);
        int ans=0;
        for(int r=0;r<siz;++r){
            while(st.size()>1&&heights[st.top()]>heights[r]){
                int h=st.top();
                st.pop();
                int w=r-1-st.top();
                ans=max(ans,w*heights[h]);
            }
            st.push(r);
        }
        return ans;
    }
};

leetcode 85

85
 class Solution {
    vector<vector<int>>H;
    int get_S(int i){
        int S=0;
        H[i].push_back(-1);
        int siz=H[i].size();
        stack<int>st;
        st.push(-1);
        for(int r=0;r<siz;++r){
            while(st.size()>1&&H[i][st.top()]>H[i][r]){
                int h=st.top();
                st.pop();
                int w=r-1-st.top();
                S=max(S,w*H[i][h]);
            }
            st.push(r);
        }
        return S;
    }
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        int n=matrix.size(),m=matrix[0].size();

        H.resize(n);
        for(int i=0;i<n;++i)H[i].resize(m);

        for(int i=0;i<n;++i){
            for(int j=0;j<m;++j){
                if(i==0)H[i][j]=matrix[i][j]-'0';
                else{
                    if(matrix[i][j]=='0')H[i][j]=0;
                    else H[i][j]=H[i-1][j]+1;
                }
            }
        }

        int ans=0;
        for(int i=0;i<n;++i){
            ans=max(ans,get_S(i));
        }
        return ans;
    }
};

leetcode 1504

1504
 class Solution {
public:
    int numSubmat(vector<vector<int>>& mat) {
        int n=mat.size(),m=mat[0].size();
        vector<int>st(m+1),h(m+1);
        int top;
        int ans=0;
        for(int i=0;i<n;++i){
            for(int j=0;j<m;++j){
                if(mat[i][j]==0)h[j]=0;
                else h[j]++;
            }
            top=-1;
            h[m]=0;
            for(int r=0;r<=m;++r){
                while(top!=-1&&h[st[top]]>=h[r]){
                    if(h[st[top]]==h[r]){
                        top--;
                        continue;
                    }
                    int cur=st[top--];
                    int l=top==-1?-1:st[top];
                    int hl=l==-1?0:h[l];
                    int w=r-l-1;
                    int leve=h[cur]-max(hl,h[r]);
                    ans+=(w+1)*w/2*leve;
                }
                st[++top]=r;
            }
        }
        return ans;
    }
};
posted @ 2026-01-12 19:52  射杀百头  阅读(3)  评论(0)    收藏  举报