답안 #945263

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
945263 2024-03-13T15:30:20 Z RGBB Vrtić (COCI18_vrtic) C++14
144 / 160
2000 ms 194320 KB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
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;
            vector<int> sv(tsi), tout(tsi);
            for(int k = i; k <= j; k++) sv[k - i] = b[k];
            tout[0] = sv[0];
            for(int k = 1; k < tsi; k++) {
                if(k % 2) tout[(k + 1) / 2] = sv[k];
                else tout[tsi - k / 2] = sv[k];
            }
            ran[i][j] = abs(tout[tsi - 1] - tout[0]);
            for(int k = 0; k < tsi - 1; k++) ran[i][j] = max(ran[i][j], abs(tout[k + 1] - tout[k]));
            dis[i][j] = tout;
        }
    }
}

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});
    random_shuffle(mp.begin(), mp.end());
}

/*
Hash func:
Base 16 digit, base 150, mod 1e9 + 7;
*/

const ll MOD = 100000000105583;

ll 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;
gp_hash_table<ll, bool> memo;
bool dfs(int p, vector<pi>& freq, int cap, ll curHash) {
    if(memo.find(curHash) != memo.end()) return false;
    memo[curHash] = true;
    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.clear();
    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 = 1e9;
    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:52:15: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   52 |     for(auto& [i, j]: tmp) mp.push_back({i, j});
      |               ^
vrtic.cpp: In function 'bool dfs(int, std::vector<std::pair<int, int> >&, int, ll)':
vrtic.cpp:75: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]
   75 |     for(int i = 0; i < freq.size(); i++) {
      |                    ~~^~~~~~~~~~~~~
vrtic.cpp:76:15: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   76 |         auto& [a, b] = freq[i];
      |               ^
vrtic.cpp: In function 'void processAnswer()':
vrtic.cpp:105:30: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  105 |             if(cyc[j].size() != i) continue;
      |                ~~~~~~~~~~~~~~^~~~
vrtic.cpp: In function 'void solve()':
vrtic.cpp:119: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]
  119 |     for(int i = 0; i < mp.size(); i++) {
      |                    ~~^~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 1112 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 3420 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 860 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 860 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 860 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 2088 KB Output is correct
2 Correct 45 ms 7872 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 23 ms 5568 KB Output is correct
2 Correct 160 ms 26772 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 10 ms 4068 KB Output is correct
2 Correct 436 ms 51472 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 39 ms 6348 KB Output is correct
2 Correct 1367 ms 95820 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 36 ms 6216 KB Output is correct
2 Execution timed out 2048 ms 194320 KB Time limit exceeded
3 Halted 0 ms 0 KB -