답안 #945317

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
945317 2024-03-13T15:57:01 Z RGBB Vrtić (COCI18_vrtic) C++14
160 / 160
590 ms 4700 KB
#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> pi;

const int MAX = 150;

int n;

int a[MAX], b[MAX], outp[MAX];

int ran[MAX][MAX];
vector<int> dis[MAX][MAX];
void calcRan() {
    for(int i = 0; i < n; i++) {
        for(int j = i; j < n; j++) {
            int tsi = j - i + 1;
            dis[i][j].resize(tsi);
            dis[i][j][0] = b[i];
            for(int k = 1; k < tsi; k++) {
                if(k % 2) dis[i][j][(k + 1) / 2] = b[k + i];
                else dis[i][j][tsi - k / 2] = b[k + i];
            }
            ran[i][j] = abs(dis[i][j][tsi - 1] - dis[i][j][0]);
            for(int k = 0; k < tsi - 1; k++) ran[i][j] = max(ran[i][j], abs(dis[i][j][k + 1] - dis[i][j][k]));
        }
    }
}

int g;
vector<int> cyc[MAX];
vector<pi> mp;
void calcCycles() {
    vector<bool> flag(n);
    for(int i = 0; i < n; i++) {
        if(flag[i]) continue;
        int cur = i;
        while(!flag[cur]) {
            flag[cur] = true;
            cyc[g].push_back(cur);
            cur = a[cur];
        }
        g++;
    }
    map<int, int> tmp;
    for(int i = 0; i < g; i++) tmp[cyc[i].size()]++;
    for(auto& [i, j]: tmp) mp.push_back({i, j});
    reverse(mp.begin(), mp.end());
}

/*
Hash func:
16 digit, base 150
*/

const int MOD = 1e7 + 19;

int origHash, base[16];
void calcBase() {
    base[0] = 1;
    for(int i = 1; i < 16; i++) base[i] = (150 * base[i - 1]) % MOD;
}

vector<int> ord;
bitset<MOD> memo;
bool dfs(int p, vector<pi>& freq, int cap, int curHash) {
    if(memo[curHash]) return false;
    memo[curHash] = 1;
    if(p == n) return true;
    for(int i = 0; i < freq.size(); i++) {
        auto& [a, b] = freq[i];
        if(!b) continue;
        if(ran[p][p + a - 1] > cap) continue;
        b--;
        ord.push_back(a);
        curHash -= base[i];
        curHash = (curHash + MOD) % MOD;
        if(dfs(p + a, freq, cap, curHash)) return true;
        b++;
        ord.pop_back();
        curHash += base[i];
        curHash %= MOD;
    }
    return false;
}

bool isGood(int cap) {
    ord.clear();
    memo.reset();
    vector<pi> freq = mp;
    return dfs(0, freq, cap, origHash);
}

void processAnswer() {
    vector<bool> flag(g);
    int sum = 0;
    for(int i: ord) {
        for(int j = 0; j < g; j++) {
            if(flag[j]) continue;
            if(cyc[j].size() != i) continue;
            flag[j] = true;
            for(int k = 0; k < i; k++) {
                outp[cyc[j][k]] = dis[sum][sum + i - 1][k];
            }
            break;
        }
        sum += i;
    }
    for(int i = 0; i < n - 1; i++) cout << outp[i] << " ";
    cout << outp[n - 1] << "\n";
}

void solve() {
    for(int i = 0; i < mp.size(); i++) {
        origHash += base[i] * mp[i].second;
        origHash %= MOD;
    }
    int l = 0;
    int r = 0;
    for(int i = 0; i < n; i++) r = max(r, b[i]);
    while(r - l > 1) {
        int m = (l + r) / 2;
        if(isGood(m)) r = m;
        else l = m;
    }
    if(isGood(l)) {
        cout << l << "\n";
        processAnswer();
    }
    else {
        cout << r << "\n";
        isGood(r);
        processAnswer();
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n;
    for(int i = 0; i < n; i++) {
        cin >> a[i];
        a[i]--;
    }
    for(int i = 0; i < n; i++) cin >> b[i];
    sort(b, b + n);
    calcRan();
    calcCycles();
    calcBase();
    solve();
}

Compilation message

vrtic.cpp: In function 'void calcCycles()':
vrtic.cpp:47:15: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   47 |     for(auto& [i, j]: tmp) mp.push_back({i, j});
      |               ^
vrtic.cpp: In function 'bool dfs(int, std::vector<std::pair<int, int> >&, int, int)':
vrtic.cpp:70:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   70 |     for(int i = 0; i < freq.size(); i++) {
      |                    ~~^~~~~~~~~~~~~
vrtic.cpp:71:15: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   71 |         auto& [a, b] = freq[i];
      |               ^
vrtic.cpp: In function 'void processAnswer()':
vrtic.cpp:100:30: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  100 |             if(cyc[j].size() != i) continue;
      |                ~~~~~~~~~~~~~~^~~~
vrtic.cpp: In function 'void solve()':
vrtic.cpp:114:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  114 |     for(int i = 0; i < mp.size(); i++) {
      |                    ~~^~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2140 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 4700 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2140 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2136 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2140 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 2904 KB Output is correct
2 Correct 22 ms 3160 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 3676 KB Output is correct
2 Correct 79 ms 3868 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 3672 KB Output is correct
2 Correct 109 ms 3676 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 4696 KB Output is correct
2 Correct 275 ms 4696 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 13 ms 4700 KB Output is correct
2 Correct 590 ms 4700 KB Output is correct