Submission #582107

#TimeUsernameProblemLanguageResultExecution timeMemory
582107KoDBoarding Passes (BOI22_passes)C++17
100 / 100
205 ms18880 KiB
#include <bits/stdc++.h> using std::vector; using std::array; using std::pair; using std::tuple; using ll = long long; template <class F> struct fixed : private F { explicit fixed(F&& f) : F(std::forward<F>(f)) {} template <class... Args> decltype(auto) operator()(Args&&... args) const { return F::operator()(*this, std::forward<Args>(args)...); } }; template <class T> constexpr T infty = std::numeric_limits<T>::max() / 2; template <class T> void setmin(T& x, const T& y) { if (x > y) { x = y; } } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); std::string S; std::cin >> S; const int N = (int)S.size(); const int G = 15; array<vector<int>, G> pos = {}; for (int i = 0; i < N; ++i) { pos[S[i] - 'A'].push_back(i); } array<vector<int>, G> accum = {}; accum.fill(vector(N + 1, 0)); for (int i = 0; i < N; ++i) { for (int k = 0; k < G; ++k) { accum[k][i + 1] = accum[k][i]; } accum[S[i] - 'A'][i + 1] += 1; } array<array<vector<ll>, G>, G> precalc = {}; for (int i = 0; i < G; ++i) { for (int j = 0; j < G; ++j) { const int n = (int)pos[i].size(); precalc[i][j].resize(n + 1); for (const int x : pos[i]) { precalc[i][j][0] += accum[j][N] - accum[j][x]; } for (int k = 0; k < n; ++k) { const int x = pos[i][k]; ll next = precalc[i][j][k]; next -= accum[j][N] - accum[j][x]; next += accum[j][x]; precalc[i][j][k + 1] = next; } } } vector<ll> dp(1 << G, infty<ll>); dp[0] = 0; for (int set = 0; set < (1 << G); ++set) { for (int add = 0; add < G; ++add) { if (set >> add & 1) { continue; } const int n = pos[add].size(); const auto calc = [&](const int k) { ll ret = 0; for (int i = 0; i < G; ++i) { if (set >> i & 1) { ret += precalc[add][i][k]; } } return ret * 2 + (ll)k * (k - 1) / 2 + (ll)(n - k) * (n - k - 1) / 2; }; int l = -1, r = n + 1; while (r - l > 2) { const int m = (l + r) / 2; if (calc(m) > calc(m + 1)) { l = m; } else { r = m + 1; } } setmin(dp[set | (1 << add)], dp[set] + calc(l + 1)); } } const ll ans = dp[(1 << G) - 1]; std::cout << ans / 2; if (ans % 2 == 1) { std::cout << ".5"; } std::cout << '\n'; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...