제출 #1252754

#제출 시각아이디문제언어결과실행 시간메모리
1252754LucaLucaMCopy and Paste 3 (JOI22_copypaste3)C++20
62 / 100
497 ms49864 KiB
#include <iostream> #include <vector> #include <algorithm> #include <cassert> #include <map> #include <random> using ll = long long; #define debug(x) #x << " = " << x << '\n' const ll INF = 1e18; std::mt19937 rng(123); std::map<int, std::vector<int>> where; struct stringHash { std::vector<int> pref; std::vector<int> value; std::vector<int> p; const int mod = 1e9 + 321; const int B = 31; int n; void init(std::string s) { n = (int) s.size(); pref.resize(n + 1, 0); p.resize(n + 1); p[0] = 1; for (int i = 1; i <= n; i++) { p[i] = (ll) p[i - 1] * B % mod; } value.resize(256); for (int &x : value) { x = rng() % mod; } for (int i = 1; i <= n; i++) { pref[i] = pref[i - 1] + (ll) value[s[i]] * p[i] % mod; pref[i] %= mod; } } int queryHash(int l, int r) { int ret = pref[r] - pref[l - 1]; if (ret < 0) { ret += mod; } // teoretic trebuie sa inmultesc cu B^-l (devastator) // dar o sa inmultesc cu B^(n-l) (asta e mega smart) return (ll) ret * p[n - l] % mod; } }; signed main() { std::ios_base::sync_with_stdio(false); std::cin.tie(0); int n; std::cin >> n; std::string s; std::cin >> s; s = '$' + s; int A, B, C; std::cin >> A >> B >> C; std::vector<std::vector<ll>> dp(n + 2, std::vector<ll>(n + 2, +INF)); for (int i = 1; i <= n; i++) { dp[i][i - 1] = 0; dp[i][i] = A; } stringHash hash1; hash1.init(s); std::vector<int> next(n + 1, -1); for (int len = 1; len <= n; len++) { for (int i = 1; i + len - 1 <= n; i++) { where[hash1.queryHash(i, i + len - 1)].push_back(i); next[i] = -1; } for (const auto &[h, ids] : where) { for (int i = 0, j = 0; i < (int) ids.size(); i++) { while (j < (int) ids.size() && ids[j] < ids[i] + len) { j++; } next[ids[i]] = (j == (int) ids.size()? -1 : ids[j]); } } where.clear(); for (int i = 1; i + len - 1 <= n; i++) { dp[i][i + len - 1] = std::min(dp[i][i + len - 1], std::min(dp[i][i + len - 2], dp[i + 1][i + len - 1]) + A); } for (int i = 1; i + len - 1 <= n; i++) { if (next[i] != -1) { int j = i; int cnt = 0; // de cate ori dau paste while (next[j] != -1) { j = next[j]; cnt++; dp[i][j + len - 1] = std::min(dp[i][j + len - 1], B + dp[i][i + len - 1] + (ll) (cnt + 1) * C + (ll) (j - i - cnt * len) * A); } } } } std::cout << dp[1][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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...