Submission #1133602

#TimeUsernameProblemLanguageResultExecution timeMemory
1133602jerzykAncient Books (IOI17_books)C++20
100 / 100
128 ms28884 KiB
#include <bits/stdc++.h>
#include "books.h"

using namespace std;
#define pb push_back
#define st first
#define nd second
typedef long long ll;
typedef long double ld;
const ll I = 1000'000'000'000'000'000LL;
const int II = 2'000'000'000;
const ll M = 1000'000'007LL;
const int N = 1000'007;
bool vis[N];
int tab[N], rp[N], lp[N];
vector<pair<int, int>> inter;
int dis[N];

int DoDis(int n, int s)
{
    int l, r, nl, nr, nd;
    l = s; r = s;
    for(int i = 0; i < n; ++i) dis[i] = II;
    dis[s] = 0;
    nd = 0;
    nl = lp[s]; nr = rp[s];
    while(l != nl || r != nr)
    {
        l = max(l - 1, nl); r = min(r + 1, nr);
        dis[l] = min(dis[l], nd); dis[r] = min(dis[r], nd);
        nl = min(nl, min(lp[r], lp[l])); nr = max(nr, max(rp[r], rp[l]));
    }
    while(l != 0 || r != n - 1)
    {
        //cerr << "R: " << l << " " << r << "\n";
        nd = max(dis[l], dis[r]) + 1;
        nl = max(0, l - 1); nr = min(n - 1, r + 1);
        while(l != nl || r != nr)
        {
            l = max(l - 1, nl); r = min(r + 1, nr);
            dis[l] = min(dis[l], nd); dis[r] = min(dis[r], nd);
            nl = min(nl, min(lp[r], lp[l])); nr = max(nr, max(rp[r], rp[l]));
        }
    }
    int ans = 0;
    for(int i = 0; i < (int)inter.size(); ++i)
        if(inter[i].nd >= s)
        {
            ans = dis[inter[i].st];
            break;
        }
    //cerr << "D: " << ans << "\n";
    return ans;
}

int Dl(int s)
{
    for(int i = s - 1; i >= 0; --i)
        if(tab[i] != i)
            return s - i;
    return 0;
}

int Dr(int s, int n)
{
    for(int i = s + 1; i < n; ++i)
        if(tab[i] != i)
            return i - s;
    return 0;
}

ll minimum_walk(vector<int> _p, int _s)
{
    int n = (int)_p.size();
    ll ans = 0LL;
    for(int i = 0; i < n; ++i)
    {
        rp[i] = i; lp[i] = i;
        tab[i] = _p[i];
    }
    bool czy = 0;
    for(int i = 0; i < n; ++i)
    {
        ans += (int)abs(tab[i] - i);
        if(vis[i]) continue;
        int l = i, r = i, v = i;
        vector<int> cur;
        while(!vis[v])
        {
            cur.pb(v);
            vis[v] = 1;
            l = min(l, v); r = max(r, v);
            v = tab[v];
        }
        //cerr << "FR: " << l << " " << r << "\n";
        for(int j = 0; j < (int)cur.size(); ++j)
            {rp[cur[j]] = r; lp[cur[j]] = l;}
        if(l != r)
            inter.pb(make_pair(l, r));
        if(l != r && l <= _s && r >= _s)
            czy = 1;
    }
    sort(inter.begin(), inter.end());
    if(czy)
        ans += DoDis(n, _s) * 2;
    else
    {
        int dl = Dl(_s), dr = Dr(_s, n);
        if(dl == 0 || dr == 0) 
            ans += (ll)(dl + dr) * 2LL;
    }
    int cur = 0;
    for(int i = 0; i < (int)inter.size(); ++i)
    {
        if(i != 0 && cur < inter[i].st) ans += 2LL * (ll)(inter[i].st - cur);
        cur = max(cur, inter[i].nd);
    }
    return ans;
}
#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...