zoukankan      html  css  js  c++  java
  • CodeForce 1454 F. Array Partition

    题目链接

    https://codeforces.com/problemset/problem/1454/F

    题意

    把一段长度为(n)的区间分成三段, 每段长度不为(0), 要求第一段区间的最大值等于第三段区间的最大值等于中间区间的最小值。输出是否能划分并输出方案。

    思路

    可以枚举所有可能的答案, 那么对于每一种答案,他的出现次数必定大于(3)
    我们可以用单调栈维护一下每个数左右的最大值/最小值的位置,并且统计每个数出现的位置(需要事先离散化一下).
    假设当前答案为(x), 那么 (x) 第一次出现的位置左边必须没有比它大的数, 最后一次右边同理, 那么剩下中间出现的位置我们进行枚举。
    中间出现的(x)作为最小值时离它左右俩边最近的最大值位置这段范围就是这个最小值控制的区间,只需要判断这个区间和第一次和最后一次出现位置控制的区间是否都有交集即可。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 2e5 + 50;
    int ind[maxn], len;
    inline int getid(const int &val){
        return lower_bound(ind + 1, ind + len + 1, val) - ind;
    }
    int getlen(int a[], int n){
        for(int i = 0;i <= n;i++){
            ind[i] = a[i];
        }
        sort(ind + 1, ind + n + 1);
        return unique(ind + 1, ind + n + 1) - ind - 1;
    }
    int st[maxn], Lmax[maxn], Rmax[maxn], Lmin[maxn], Rmin[maxn];
    void getLmax(int a[], int n){//左边第一个大于a[i]的数
        int cnt = 0;
        st[0] = 0;
        for(int i = 1;i <= n;i++){
            while(cnt && a[i] >= a[st[cnt]]) cnt--;
            Lmax[i] = st[cnt];
            st[++cnt] = i;
        }
    }
    void getRmax(int a[], int n){//右边第一个大于a[i]的数
        int cnt = 0;
        st[0] = n + 1;
        for(int i = n;i >= 1;i--){
            while(cnt && a[i] >= a[st[cnt]]) cnt--;
            Rmax[i] = st[cnt];
            st[++cnt] = i;
        }
    }
    void getLmin(int a[], int n){//左边第一个小于a[i]的数
        int cnt = 0;
        st[0] = 0;
        for(int i = 1;i <= n;i++){
            while(cnt && a[i] <= a[st[cnt]]) cnt--;
            Lmin[i] = st[cnt];
            st[++cnt] = i;
        }
    }
    void getRmin(int a[], int n){//右边第一个小于a[i]的数
        int cnt = 0;
        st[0] = n + 1;
        for(int i = n;i >= 1;i--){
            while(cnt && a[i] <= a[st[cnt]]) cnt--;
            Rmin[i] = st[cnt];
            st[++cnt] = i;
        }
    }
    int a[maxn];
    vector<int> v[maxn];
    int main()
    {
        std::ios::sync_with_stdio(false);
        int t;
        cin >> t;
        while(t--){
            int n;
            cin >> n;
            for(int i = 1;i <= n;i++){
                cin >> a[i];
                v[i].clear();
            }
            len = getlen(a, n);
            for(int i = 1;i <= n;i++) a[i] = getid(a[i]);
            getLmax(a, n);
            getRmax(a, n);
            getLmin(a, n);
            getRmin(a, n);
            for(int i = 1;i <= n;i++){
                v[a[i]].push_back(i);
            }
            int ok = 0;
            for(int i = 1;i <= n;i++){
                int m = v[i].size();
                if(m < 3) continue;
                if(Lmax[v[i][0]] == 0 && Rmax[v[i][m - 1]] == n + 1){
                    for(int j = 1;j < m - 1;j++){
                        int pos = v[i][j];
                        if(Lmin[pos] + 1 <= Rmax[v[i][0]] && Rmin[pos] - 1 >= Lmax[v[i][m - 1]]){
                            ok = 1;
                            cout << "YES" << endl;
                            int ansl = min(pos - 1, Rmax[v[i][0]] - 1);
                            int ansr = n - max(pos + 1, Lmax[v[i][m - 1]] + 1) + 1;
                            cout << ansl << " " << n - ansl - ansr << " " << ansr <<endl;
                            break;
                        }
                    }
                    if(ok) break;
                }
            }
            if(!ok) cout << "NO" << endl;
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    Windows 8实例教程系列 开篇
    qt 开发发布于 windeploy.exe
    qt qoci 测试验证
    vmware vmx 版本不兼容
    qt oracle
    vc qt dll
    QOCIDriver unable to create environment
    qoci 编译完 放置位置 具体根据情况
    calling 'lastError' with incomplete return type 'QSqlError' qsqlquer
    Hbase 操作工具类
  • 原文地址:https://www.cnblogs.com/Carered/p/14057228.html
Copyright © 2011-2022 走看看