2019牛客暑期多校训练营(第一场) A Equivalent Prefixes (单调队列)

本文介绍了一种通过维护单调队列来解决寻找两个数组中具有相同最小值下标的最大子区间的方法。通过确保两个队列的长度一致,可以高效地找到满足条件的最大点P。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

题意:找到最大的点 P P P,使得两个数组 a a a b b b 在区间 [ 1 , P ] [1,P] [1,P]的任意子区间中的最小值下标相同

题解:对两个数组分别维护单调递增的单调队列。 每次插入后判断队列中的元素个数是否相同,不相同直接返回答案。
这样做保证了两个数组对应区间单调性相同,子区间个数也相同。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int a[maxn],b[maxn],n,q1[maxn],q2[maxn];
int solve(){
    int f1 = 0, r1 = 0;
    int f2 = 0, r2 = 0;
    int ans;
    for(int i = 1; i <= n; i++){
        while(f1 < r1 && a[i] <= a[q1[r1-1]]) r1--;
        q1[r1++] = i;
        while(f2 < r2 && b[i] <= b[q2[r2-1]]) r2--;
        q2[r2++] = i;
        
        if(r1-f1 != r2-f2) return i-1;
        ans = i;
    }
    return ans;
}
int main(){
    while(~scanf("%d",&n)){
        for(int i = 1; i <= n; i++){
            scanf("%d",&a[i]);
        }
        for(int i = 1; i <= n; i++){
            scanf("%d",&b[i]);
        }
        printf("%d\n",solve());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值