数据结构-单调栈单调队列

求下一个更大值

//求下一个更大数
#include<bits/stdc++.h>
using namespace std;
int n, top;
int a[200010], s[200010], ans[200010];

int main(){
    scanf("%d", &n);
    for (int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
    }
    for (int i = 1; i <= n; i++){
        while (top && a[i] > a[s[top]]){
            ans[s[top--]] = i;
        }
        s[++top] = i;
    }
    for (int i = 1; i <= top; i++){
        ans[s[i]] = 0;
    }
    for (int i = 1; i <= n; i++){
        printf("%d ", ans[i]);
    }
} 

最大矩形面积

//最大矩形面积
#include<bits/stdc++.h>
using namespace std;
int n, top;
int a[200010], s[200010];
int l[200010], r[200010];

int main(){
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for (int i = 1; i <= n; i++){
        while (top && a[i] <= a[s[top]])
            top--;
        if (top)
            l[i] = s[top] + 1;
        else 
            l[i] = 1;
        s[++top] = i;
    }
    top = 0;
    for (int i = n; i >= 1; i--){
        while (top && a[i] <= a[s[top]])
            top--;
        if (top)
            r[i] = s[top] - 1;
        else
            r[i] = n;
        s[++top] = i;
    }
    long long ans = 0;
    for (int i = 1; i <= n; i++){
        ans = max(ans, 1LL * a[i] * (r[i] - l[i] + 1));
    }
    printf("%lld\n", ans);
} 

数对统计

//数对统计
#include<bits/stdc++.h>
using namespace std;
int n, top;
int a[200010], s[200010];

int main(){
    scanf("%d", &n);
    for (int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
    }
    int ans = 0;
    for (int i = 1; i <= n; i++){
        while (top && a[i] >= a[s[top]]){
            top--, ans++;
        }
        if (top){
            ans++;
        }
        s[++top] = i;
    }
    printf("%d\n", ans);
} 

动态区间最大值

//动态区间最大值
#include<bits/stdc++.h>
using namespace std;
int n, m, front = 1, rear;
int a[200010], q[200010];

int main(){
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
    }
    for (int i = 1; i <= n; i++){
        while (front <= rear  && a[i] >= a[q[rear]]){
            rear--;
        }
        q[++rear] = i;
        if (q[front] < i - m + 1){
            ++front;
        }
        if (i >= m){
            printf("%d ", a[q[front]]);
        }
    }
}  

最大连续区间和

//最大连续区间和
#include<bits/stdc++.h>
using namespace std;
int n, l, r, front = 1, rear;
int a[200001], q[200001], s[200001];
int main(){
    scanf("%d%d%d", &n, &l, &r);
    for (int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
        s[i] = s[i - 1] + a[i];
    }
    int x = l, ans = -1 << 30;// x为区间的右端点
    for (int i = 1; i <= n - l + 1; i++){ 
        while (x <= i + r - 1 && x <= n){
            while (front <= rear && s[x] > s[q[front]]){
                rear--;
            }
            q[++rear] = x++;
        }
        if (q[front] < i + l - 1){
            front++;
        }
        ans = max(ans, s[q[front]] - s[i - 1]);
    }
    printf("%d\n", ans);
}  

覆盖

//覆盖
#include<bits/stdc++.h>
using namespace std;
int n, h, ans;
int a[100001], q1[100001], front1 = 1, rear1;
int q2[100001], front2 = 1, rear2;

int main(){
    scanf("%d%d", &n, &h);
    for (int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
    }
    int j = 0, ans = 0;
    for (int i = 1; i <= n; i++){
        if (front1 <= rear1 && q1[front1] < i){
            front1++;
        }
        if (front2 <= rear2 && q2[front2] < i){
            front2++;
        }
        while (j <= n && (j <= i || a[q1[front1]] - a[q2[front2]] <= h)){
            j++;
            if(j > n){
                break;
            }
            while (front1 <= rear1 && a[j] >= a[q1[rear1]]){
                rear1--;
            }
            q1[++rear1] = j;
            while (front2 <= rear2 && a[j] <= a[q2[rear2]]){
                rear2--;
            }
            q2[++rear2] = j;
        }
        ans = max(ans, j - i);
    }
    printf("%d\n", ans);
}  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值