zoukankan      html  css  js  c++  java
  • 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
    ", i -1);
                    //goto out;
                     flag = 1;break;
                   
                }
                
                
            }if(!flag)
                printf("%d
    ", 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)

  • 相关阅读:
    利用performSelectorInBackground和performSelectorOnMainThread实现多线程刷新UI
    iOS之NSCocoaErrorDomain Code=3840
    iOS之原生地图与高德地图
    iOS之Storyboard References
    iOS之内购
    iOS之上线被拒
    iOS之可拖拽重排的CollectionView
    iOS之内购
    ios专题
    ios专题
  • 原文地址:https://www.cnblogs.com/DWVictor/p/11210271.html
Copyright © 2011-2022 走看看