답안 #239089

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
239089 2020-06-14T10:56:44 Z kartel Vrtić (COCI18_vrtic) C++14
80 / 160
144 ms 262148 KB
#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
#define in(x) freopen(x, "r", stdin)
#define out(x) freopen(x, "w", stdout)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-O3")
#define F first
#define S second
#define pb push_back
#define N +100500
#define M ll(1e9 + 7)
#define sz(x) (int)x.size()
#define re return
#define oo ll(1e9)
#define el '\n'
#define pii pair <int, int>
using namespace std;
//using namespace __gnu_pbds;
//typedef tree <int, null_type, less_equal <int> , rb_tree_tag, tree_order_statistics_node_update> ordered_set;
typedef long long ll;
typedef long double ld;

struct str{
    int val, len, last;
};

int cur = 1e9, bestfriend[N], surprize[N], i, l, r, n, ans[N], maybeans[N], num[N], cntcycles, mask, pr, nm;
bool mk[N], mrk[N];
vector <int> cycle[N];

str f[(1 << 20)][25];

int func(int i, int j)
{
    for (int j = 1; j <= n; j++) maybeans[j] = 0;
    j = n - j;
    int l = 0;
    int r = sz(cycle[i]) - 1;

    while (l <= r)
    {
        maybeans[cycle[i][r]] = surprize[j];
        j--;
        r--;
        if (l > r) break;
        maybeans[cycle[i][l]] = surprize[j];
        j--;
        l++;
    }

    int maybecur = 0;

//    cerr << i << el;
//
    for (int i = 1; i <= n; i++) maybecur = max(maybecur, abs(maybeans[i] - maybeans[bestfriend[i]]));
//
//    cerr << el << maybecur << el;

    return maybecur;
}

void findcycle(int v)
{
    if (mrk[v]) return;
    mrk[v] = 1;

    cycle[cntcycles].pb(v);

    findcycle(bestfriend[v]);
}

void restoreans()
{
    int i = cntcycles - 1;
    mask = (1 << cntcycles) - 1;

    int pr = nm;
    while (mask != 0)
    {
        int nmask = mask ^ (1 << pr);
        num[i--] = pr;
        pr = f[mask][pr].last;
//        cerr << pr << el;
        mask = nmask;
    }

//    for (i = 0; i < cntcycles; i++) cerr << num[i] << el;

//    cerr << "YES" << el;

    int j = n;

    for (i = 0; i < cntcycles; i++)
    {
        int l = 0;
        int r = sz(cycle[num[i]]) - 1;

        while (l <= r)
        {
            ans[cycle[num[i]][r]] = surprize[j];
            j--;
            r--;
            if (l > r) break;
            ans[cycle[num[i]][l]] = surprize[j];
            j--;
            l++;
        }
    }
//    cerr << "YES" << el;
}

int main()
{
    srand(time(0));
    ios_base::sync_with_stdio(0);
    iostream::sync_with_stdio(0);
    ios::sync_with_stdio(0);
    cin.tie(NULL);
    cout.tie(NULL);

//    in("D:/cpp/1/input.txt");
//    out("output.txt");

    cin >> n;
    for (i = 1; i <= n; i++) cin >> bestfriend[i];
    for (i = 1; i <= n; i++) cin >> surprize[i];

    sort(surprize + 1, surprize + 1 + n);
    i = 1;
    while (i < n && bestfriend[i] == i + 1) i++;

    if (i >= n && bestfriend[n] == 1)
    {

        l = 1;
        r = n;
        i = n;

        while (l <= r)
        {
            ans[r] = surprize[i];
            r--;
            i--;
            if (l > r) break;
            ans[l] = surprize[i];
            i--;
            l++;
        }

        cur = 0;

        for (i = 1; i <= n; i++) cur = max(cur, abs(ans[i] - ans[bestfriend[i]]));

        cout << cur << el;

        for (i = 1; i <= n; i++) cout << ans[i] << " ";
    }
    else
    {
    cntcycles = -1;
    for (i = 1; i <= n; i++)
    {
        if (mrk[i]) continue;

        cntcycles++;

        findcycle(i);
    }

    cntcycles++;


    for (mask = 0; mask < (1 << cntcycles); mask++)
        for (pr = 0; pr <= cntcycles; pr++)
          f[mask][pr].val = 1e9;

    for (i = 0; i < n; i++) f[0][i].val = f[0][i].len = 0;

    for (mask = 0; mask < (1 << cntcycles); mask++)
    {
        for (pr = 0; pr < cntcycles; pr++)
        {
            for (i = 0; i < cntcycles; i++)
            {
                int nmask = (mask | (1 << i));

                if (nmask == mask) continue;

//                cerr << mask << " " << f[mask][pr].len << el;

                int value = func(i, f[mask][pr].len);

                if (f[nmask][i].val > max(f[mask][pr].val, value))
                {
                    f[nmask][i].val = max(f[mask][pr].val, value);
                    f[nmask][i].last = pr;
                    f[nmask][i].len = f[mask][pr].len + sz(cycle[i]);
                }
            }
        }
    }

//    cout << f[1][1].val << " " <<

    cur = 1e9;
    nm = 0;
    for (pr = 0; pr < cntcycles; pr++)
        if (cur > f[(1 << cntcycles) - 1][pr].val)
    {
        cur = f[(1 << cntcycles) - 1][pr].val;
        nm = pr;
    }

    cout << cur << el;

    restoreans();

    for (i = 1; i <= n; i++) cout << ans[i] << " ";
    }
}

/*
8 8
...).).*
*....)..
.)*(..).
(*)((...
.)).)(..
.)(.)..(
...).(.*
M.......
*/
//
//110000
//1100
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 2688 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 2688 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 3968 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 21 ms 3968 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 21 ms 3968 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Runtime error 129 ms 262148 KB Execution killed with signal 9 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 144 ms 262148 KB Execution killed with signal 9 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 126 ms 262144 KB Execution killed with signal 9 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 129 ms 262148 KB Execution killed with signal 9 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 129 ms 262148 KB Execution killed with signal 9 (could be triggered by violating memory limits)
2 Halted 0 ms 0 KB -