A.Equivalent Prefixes

题目大意:等价数组定义为(1≤l≤r≤m)中,所有的子区间都满足最小值下标相等,找出最大的m。

题解:我们要找到最大的m,就要保证两个数组的所有子区间最小值下标相等

所以用一个单调栈来维护一个单调递增的序列,栈底为最小值,保证最小值下标相等,以及栈中元素相同

即可保证子区间最小值下标相等

例如:ABCDE 

假设C是最小值,A这个区间肯定是可以,AB这个区间肯定是要满足递增或者递减

ABC这个区间就已经满足,因为最小值就是C,同理ABCD,ABCDE,BC,BCD,BCDE,CD,CDE满足。

然后就是DE,如果两个数组不满足递增或递减,那么栈中元素必定不同,那么m就是D下标,反之就是E。

C++代码

 

#include<bits/stdc++.h>
using namespace std;
const int maxn=200050;
int a[maxn],b[maxn];
int main(int argc, char const *argv[])
{
    int n ;
    while(cin >> n){
    for(int i = 1;i <= n ; i ++) cin >> a[i];
        for(int i = 1;i <= n ; i++) cin >> b[i];
            stack<int> s1,s2;
        int flag = 0;
        for(int i = 1;i <= n ; i++){
            while(!s1.empty() && s1.top() > a[i]) s1.pop();
            while(!s2.empty() && s2.top() > b[i]) s2.pop();
            s1.push(a[i]);s2.push(b[i]);
            cout << s1.size() << " " << s2.size() << endl;
            if(s1.size() != s2.size()){
                printf("%d\n", i -1);
                //goto out;
                 flag = 1;break;
               
            }
            
            
        }if(!flag)
            printf("%d\n", n);
    }
    return 0;
}

 

官方题解

做法 1

• 题中的“equivalent”等价于笛卡尔树相同
• 二分答案,比较两个前缀的笛卡尔树 O(n log n)

笛卡尔树:点击此处


做法 2

• 对于数组 a,定义 lasta
(i) = max { j : j < i and aj > ai
}
• 如果 lasta = lastb,那么数组 a 和 b“equivalent”
证明:n, last(n), last(last(n)), ... 是笛卡尔树的最右路径,递归构造
• 单调队列求 last 并比较 O(n)

 

posted @ 2019-07-18 21:55  DWVictor  阅读(214)  评论(0编辑  收藏  举报