Submission #1310226

#TimeUsernameProblemLanguageResultExecution timeMemory
1310226edoSwap (BOI16_swap)C++20
100 / 100
671 ms232544 KiB
#include <bits/stdc++.h>

using namespace std;
using ll   = long long;
using vi   = vector<int>;
using vll  = vector<ll>;
using vvi  = vector<vi>;
using vvll = vector<vll>;
using pii  = pair<int,int>;
using pll  = pair<ll,ll>;
using ui    = unsigned int;
using ull   = unsigned long long;
using pui   = pair<ui,ui>;
using pull  = pair<ull,ull>;
using i128 = __int128_t;

template<typename T>
using vc = std::vector<T>;


#define YES cout << "YES\n"
#define NO  cout << "NO\n"
#define yes cout << "yes\n"
#define no  cout << "no\n"
#define Yes cout << "Yes\n"
#define No  cout << "No\n"

template<typename T> void sc(T &x) { cin >> x; }
template<typename T, typename U> void sc(pair<T,U> &p) { sc(p.first), sc(p.second); }
template<typename T> void sc(vector<T> &v) { for (auto &x : v) sc(x); }
template<typename... A> void sc(A&... a) { (sc(a), ...); }


template<typename T> void _pt(const T &x){cout << x;}
template<typename T, typename U> void _pt(const pair<T,U> &p){_pt(p.first); cout << ' '; _pt(p.second);}
template<typename T> void _pt(const vector<T> &v){bool f=1; for(auto &x:v){if(!f) cout<<' '; _pt(x); f=0;}}
template<typename... A> void pt(const A&... a){(_pt(a), ...);}


template<typename T, typename U> bool umin(T &a, const U &b) { return b < a ? (a = b, true) : false; }
template<typename T, typename U> bool umax(T &a, const U &b) { return b > a ? (a = b, true) : false; }
template<typename T> T maxel(const vector<T>& v){ return *max_element(v.begin(), v.end()); }
template<typename T> T minel(const vector<T>& v){ return *min_element(v.begin(), v.end()); }
template<typename T, int N> T maxel(T (&a)[N]) { return *max_element(a, a + N); }
template<typename T, int N> T minel(T (&a)[N]) { return *min_element(a, a + N); }


template<typename C, typename T> auto lb(C& c, const T& x){ return std::lower_bound(c.begin(), c.end(), x); }
template<typename C, typename T> auto ub(C& c, const T& x){ return std::upper_bound(c.begin(), c.end(), x); }

template<typename T> auto lb(std::set<T>& s, const T& x){ return s.lower_bound(x); }
template<typename T> auto ub(std::set<T>& s, const T& x){ return s.upper_bound(x); }
template<typename T> auto lb(const std::set<T>& s, const T& x){ return s.lower_bound(x); }
template<typename T> auto ub(const std::set<T>& s, const T& x){ return s.upper_bound(x); }

#define GET_MACRO(_1,_2,_3,_4,NAME,...) NAME
#define FOR1(n)            for (int i=0; i<(n); ++i)
#define FOR2(i,n)          for (int i=0; i<(n); ++i)
#define FOR3(i,l,r)        for (int i=(l); i<(r); ++i)
#define FOR4(i,l,r,k)      for (int i=(l); i<(r); i+=(k))
#define FOR(...)           GET_MACRO(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define ROF1(n)            for (int i=(n)-1; i>=0; --i)
#define ROF2(i,n)          for (int i=(n)-1; i>=0; --i)
#define ROF3(i,l,r)        for (int i=(r)-1; i>=(l); --i)
#define ROF4(i,l,r,k)      for (int i=(r)-1; i>=(l); i-=(k))
#define ROF(...)           GET_MACRO(__VA_ARGS__, ROF4, ROF3, ROF2, ROF1)(__VA_ARGS__)
#define all(c)   (c).begin(), (c).end()
#define allr(c)  (c).rbegin(), (c).rend()
#define eb       emplace_back
#define mp       make_pair
#define mt       make_tuple
#define fi       first
#define se       second
#define pb       push_back
#define trav(x,a) for (auto &x : (a))
#define sz(a) ((int)(a).size())
#define mem(a,v) memset(a, v, sizeof(a))
#define nl pt("\n")

const int nax = 2e5, J = 36;
int a[nax + 1];
bool P[nax + 1][J];
vi dp[nax][J]; // bfs poredak

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    sc(n);
    FOR(i, 1, n + 1) 
        sc(a[i]);

    P[1][0] = 1;
    FOR(i, 1, n / 2 + 1) {
        FOR(j, J) {
            if(!P[i][j]) continue;
            int d = j >> 1;
            int s = j & 1; 
            int sa = i >> d ^ s;
            if((i << 1 | 1) < n + 1) {
                if(a[i << 1 | 1] < a[i << 1] && a[sa] > a[i << 1 | 1]) {
                    // desno je najmanje 
                    P[i << 1][0] = P[i << 1 | 1][j + 2] = P[i << 1][j + 2] = P[i << 1 | 1][1] = 1;
                    // mogu ostati ili se zamijeniti
                }
                else {
                    // desni ostaje
                    P[i << 1 | 1][0] = 1;
                    // lijevi samo ako moze da se mijenja sa pretkom
                    P[i << 1][a[sa] > a[i << 1] ? j + 2 : 0] = 1;
                }
            }
        }
    }

    auto combine = [&](vi& comb, const vi& A, const vi& B) {
        int N = sz(A), M = sz(B);
        int i = 0, j = 0;
        for(int l = 1; i < N || j < M; l <<= 1) {
            FOR(k, l) {if(i + k < N) {comb.pb(A[i + k]);} else break;}
            FOR(k, l) {if(j + k < M) {comb.pb(B[j + k]);} else break;}
            i += l; j += l;
        }
    };

    ROF(i, 1, n + 1) {
        FOR(j, J) {
            if(!P[i][j]) continue;
            int d = j >> 1;
            int s = j & 1;
            int sa = i >> d ^ s;
            if((i << 1 | 1) < n + 1) {
                if(a[i << 1 | 1] < a[i << 1] && a[sa] > a[i << 1 | 1]) {
                    vi desno = {a[i << 1 | 1]};
                    vi lijevo = desno;
                    combine(desno, dp[i << 1][0], dp[i << 1 | 1][j + 2]);
                    combine(lijevo, dp[i << 1][j + 2], dp[i << 1 | 1][1]);
                    dp[i][j] = min(lijevo, desno);
                }
                else {
                    dp[i][j] = {min(a[sa], a[i << 1])};
                    combine(dp[i][j], dp[i << 1][a[sa] > a[i << 1] ? j + 2 : 0], dp[i << 1 | 1][0]);
                }
            }
            else if((i << 1) < n + 1) {
                // samo lijevo 
                dp[i][j] = {min(a[sa], a[i << 1]), max(a[sa], a[i << 1])};
            }
            else {
                dp[i][j] = {a[sa]};
            }
        }

        // MEMORIJU OSLOBODITI
        if((i << 1 | 1) <= n) {
            FOR(j, 2) {
                FOR(k, J) {
                    if(P[2 * i + j][k]) {
                        dp[2*i+j][k].clear();
                        dp[2*i+j][k].shrink_to_fit();
                    }
                }
            }
        }
    }

    pt(dp[1][0]); nl;

        
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...