Submission #655479

#TimeUsernameProblemLanguageResultExecution timeMemory
655479jophyyjhGondola (IOI14_gondola)C++14
90 / 100
1063 ms5580 KiB
/**
 * Quite simple, though a little bit tedious?
 * 
 * Time Complexity: O(n * log(n))       (Full solution)
 * Implementation 1             (Math, implementation)
*/
 
#include <bits/stdc++.h>
#include "gondola.h"

typedef long long   ll;
typedef std::vector<int>    vec;

const ll MOD = 1e9 + 9;


vec cyc_shift(int n, int input_seq[]) {
    int original = -1, original_pos = -1;
    for (int k = 0; k < n && original == -1; k++) {
        if (input_seq[k] <= n)
            original = input_seq[k], original_pos = k;
    }
    vec shift(n);
    int delta = (original != -1 ? original_pos + 1 - original : 0);
    for (int k = 0; k < n; k++)
         shift[k] = input_seq[(k + delta + n) % n];
    return shift;
}

int valid(int n, int input_seq[]) {
    vec shift = cyc_shift(n, input_seq);
    bool ok = true;
    std::set<int> appeared;
    for (int k = 0; k < n && ok; k++) {
        if (shift[k] <= n) {
            ok &= (shift[k] == k + 1);
        } else {
            ok &= (appeared.find(shift[k]) == appeared.end());
            appeared.emplace(shift[k]);
        }
    }
    return ok;
}

int replacement(int n, int gondola_seq[], int replacement_seq[]) {
    assert(valid(n, gondola_seq));
    vec shift = cyc_shift(n, gondola_seq);
    int repl_len = 0;
    vec count(n + 1, 0);
    memset(replacement_seq, -1, sizeof(int) * 250001);
    for (int k = 0; k < n; k++) {
        if (shift[k] > n) {
            repl_len = std::max(repl_len, shift[k] - n);
            replacement_seq[shift[k] - n - 1] = k + 1;
        }
    }
    for (int k = repl_len - 1, last = -1; k >= 0; k--) {
        if (replacement_seq[k] == -1) {
            replacement_seq[k] = replacement_seq[last];
            replacement_seq[last] = n + k + 1;
        }
        last = k;
    }
    return repl_len;
}

int countReplacement(int n, int input_seq[]) {
    if (!valid(n, input_seq))
        return 0;
    vec shift = cyc_shift(n, input_seq);
    int max_val = 0;
    vec top;
    for (int k = 0; k < n; k++) {
        if (shift[k] > n)
            top.push_back(shift[k]);
        max_val = std::max(max_val, shift[k]);
    }
    std::sort(top.rbegin(), top.rend());
    int m = top.size();
    ll comb = 1;
    for (int t = n + 1; t <= max_val; t++) {
        int pt = -1;
        for (int step = m / 2 + 1; step >= 1; step /= 2) {
            while (pt + step < m && top[pt + step] >= t)
                pt += step;
        }
        if (pt != -1 && top[pt] == t)
            continue;
        comb *= ll(pt + 1), comb %= MOD;
    }
    bool fixed_cyc = false;
    for (int k = 0; k < n && !fixed_cyc; k++)
        fixed_cyc |= (shift[k] == k + 1);
    if (!fixed_cyc)
        comb *= ll(n), comb %= MOD;
    return int(comb);
}
#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...
#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...