2019 Hang electric field of more than 1002 school second title Beauty Of Unimodal Sequence (LIS + monotonous stack)

Topic Link

Portal

Thinking

First, we \ (A \) positive and negative side of each run \ (the LIS \) , the recording position of the front half of each \ (the LIS \) should be put in the position \ (ANS1 [I] \) , the position of the rear half \ (ANS2 [I] \) .

Dictionary program for a minimum of order, we find the first peak, and then forward traversal. In \ (i \) in this position, if it \ (LIS \) put in the position \ (POS \) , then we look at the current place \ (pos + 1 \) value is greater than its big then it shows the position of a certain ratio of the front to let in \ (POS \) better in this position (as lexicographically less, and \ ([1, i] \ ) must be filled \ ([1, pos-1 ] \) ), then we will use the current stack monotonous put less \ (pos \) the value of all the \ (pop \) away. For the latter half of us directly for each position can be covered repeatedly put.

For us the biggest dictionary order is repeated to cover the first half, second half with monotonous stack maintenance, and lexicographical just the opposite.

Code to achieve the following

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;

#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("/home/dillonh/CLionProjects/Dillonh/in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)

const double eps = 1e-8;
const int mod = 998244353;
const int maxn = 3e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;

int n;
stack<int> st;
vector<int> vec, v;
int pos[maxn];
int a[maxn], dp[maxn], ans1[maxn], ans2[maxn];

int main() {
#ifndef ONLINE_JUDGE
    FIN;
#endif
    while(~scanf("%d", &n)) {
        memset(dp, inf, sizeof(dp));
        dp[0] = 0;
        for(int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
            ans1[i] = ans2[i] = 0;
            pos[i] = inf;
            ans1[i] = lower_bound(dp + 1, dp + n + 1, a[i]) - dp;
            dp[ans1[i]] = a[i];
        }
        memset(dp, inf, sizeof(dp));
        dp[0] = 0;
        for(int i = n; i >= 1; --i) {
            ans2[i] = lower_bound(dp + 1, dp + n + 1, a[i]) - dp;
            dp[ans2[i]] = a[i];
        }
        while(!st.empty()) st.pop();
        int idx = 1, mx = ans1[1] + ans2[1];
        for(int i = 2; i <= n; ++i) {
            if(ans1[i] + ans2[i] > mx) {
                idx = i;
                mx = ans1[i] + ans2[i];
            }
        }
        pos[ans1[idx]] = a[idx];
        for(int i = idx - 1; i >= 1; --i) {
            if(ans1[i] >= ans1[idx]) continue;
            if(pos[ans1[i]+1] <= a[i]) continue;
            while(!st.empty() && ans1[i] >= ans1[st.top()]) {
                pos[ans1[st.top()]] = inf;
                st.pop();
            }
            st.push(i);
            pos[ans1[i]] = a[i];
        }
        vec.clear();
        while(!st.empty()) {
            vec.push_back(st.top());
            st.pop();
        }
        vec.push_back(idx);
        int las = idx;
        for(int i = idx + 1; i <= n; ++i) {
            if(ans2[i] == ans2[las] - 1 && a[i] < a[las]) {
                vec.push_back(i);
                las = i;
            }
        }
        int flag = 0;
        for(auto x:vec) {
            if(flag) printf(" ");
            flag = 1;
            printf("%d", x);
        }
        printf("\n");

        vec.clear();
        idx = 1, mx = ans1[1] + ans2[1];
        for(int i = 2; i <= n; ++i) {
            if(ans1[i] + ans2[i] >= mx) {
                idx = i;
                mx = ans1[i] + ans2[i];
            }
        }
        las = idx;
        vec.push_back(idx);
        for(int i = idx - 1; i >= 1; --i) {
            if(ans1[i] == ans1[las] - 1 && a[i] < a[las]) {
                vec.push_back(i);
                las = i;
            }
        }
        reverse(vec.begin(), vec.end());
        for(int i = 1; i<= n; ++i) pos[i] = inf;
        pos[ans2[idx]] = a[idx];
        while(!st.empty()) st.pop();
        for(int i = idx + 1; i <= n; ++i) {
            if(ans2[i] > ans2[idx]) continue;
            if(a[i] >= pos[ans2[i]+1]) continue;
            while(!st.empty() && ans2[i] >= ans2[st.top()]) {
                pos[ans2[st.top()]] = inf;
                st.pop();
            }
            st.push(i);
            pos[ans2[st.top()]] = a[i];
        }
        v.clear();
        while(!st.empty()) {
            v.push_back(st.top());
            st.pop();
        }
        reverse(v.begin(), v.end());
        flag = 0;
        for(auto x:vec) {
            if(flag) printf(" ");
            flag = 1;
            printf("%d", x);
        }
        for(auto x:v) {
            if(flag) printf(" ");
            flag = 1;
            printf("%d", x);
        }
        printf("\n");
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/Dillonh/p/11240083.html