NC241488. 吟游诗人
描述
输入描述
第一行三个正整数 。
第二行 个整数描述初始序列 。
第三行 个正整数描述置换 。
输出描述
一个整数表示答案。
示例1
输入:
8 1 6 0 -7 8 -1 -3 9 -8 5 4 7 2 8 3 6 5 1
输出:
3
示例2
输入:
9 6 9 -1 -7 -10 -1 -5 5 8 -10 9 7 4 1 2 8 6 5 3 9
输出:
7
C++(g++ 7.5.0) 解法, 执行用时: 1016ms, 内存消耗: 15096K, 提交时间: 2022-09-09 19:56:31
#include <bits/stdc++.h> using namespace std; typedef long long ll; void chk(int &x, int y) { if (x > y) x = y; } struct BIT { vector<int> c; BIT(int n) : c(n + 1, 1e9) {} void ins(int p, int v) { for (p++; p; p -= p & -p) chk(c[p], v); } int query(int p) { int s = 1e9; for (p++; p < c.size(); p += p & -p) chk(s, c[p]); return s; } }; int main() { ios::sync_with_stdio(0), cin.tie(0); int n, k, T; cin >> n >> k >> T; vector<int> c(n); for (int &x : c) { cin >> x; } vector<int> p(n), q(n); iota(p.begin(), p.end(), 0); for (int &x : q) { cin >> x, x--; } vector a(T + 1, vector<int>(n)); for (int t = 0; t <= T; t++) { for (int i = 0; i < n; i++) { a[t][i] = c[p[i]]; } vector<int> _p(n); for (int i = 0; i < n; i++) { _p[i] = q[p[i]]; } swap(p, _p); } ll ans = -1e13; vector<int> perm(T + 1); iota(perm.begin(), perm.end(), 0); shuffle(perm.begin(), perm.end(), mt19937(time(0))); for (int t : perm) { vector<ll> s(n + 1); for (int i = 0; i < n; i++) { s[i + 1] = s[i] + a[t][i]; } auto val = s; sort(val.begin(), val.end()); val.resize(unique(val.begin(), val.end()) - val.begin()); vector<int> pos(n + 1); for (int i = 0; i <= n; i++) { pos[i] = lower_bound(val.begin(), val.end(), s[i]) - val.begin(); } auto chk = [&](ll lim) { vector<int> f(n + 1), g(n + 1); BIT c1(val.size()), c2(val.size()); c1.ins(pos[0], f[0] = 0), c2.ins(pos[0], g[0] = 0); for (int i = 1; i <= n; i++) { int j = lower_bound(val.begin(), val.end(), s[i] - lim) - val.begin(); c1.ins(pos[i], f[i] = c1.query(j) + 1); c2.ins(pos[i], g[i] = c2.query(j) - 1); } return f[n] <= k && -g[n] >= k; }; ll l = ans, r = 1e13; if (chk(l)) continue; while (l <= r) { ll mid = (l + r) / 2; chk(mid) ? r = (ans = mid) - 1 : l = mid + 1; } } cout << ans << "\n"; return 0; }
C++(clang++ 11.0.1) 解法, 执行用时: 662ms, 内存消耗: 16092K, 提交时间: 2022-09-11 19:41:48
#include <bits/stdc++.h> const int MaxN = 2e3 + 5; const int inf = 1e9; using ll = long long; std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count()); int n, k, T, f[MaxN], b[MaxN][MaxN]; ll s[MaxN]; int c1[MaxN], c2[MaxN], dp1[MaxN], dp2[MaxN]; bool check(int a[], ll t) { for(int i = 1; i <= n; ++i) s[i] = s[i - 1] + a[i]; std::vector<ll> V(s + 1, s + n + 1); std::sort(V.begin(), V.end()); auto rk = [&](ll x) { return std::lower_bound(V.begin(), V.end(), x) - V.begin() + 1; }; std::fill(c1 + 1, c1 + n + 1, inf); std::fill(c2 + 1, c2 + n + 1, -inf); std::fill(dp1 + 1, dp1 + n + 1, inf); std::fill(dp2 + 1, dp2 + n + 1, -inf); for(int i = 1; i <= n; ++i) { if(s[i] <= t) dp1[i] = dp2[i] = 1; for(int x = n - rk(s[i] - t) + 1; x; x -= (x & -x)) { dp1[i] = std::min(dp1[i], c1[x] + 1); dp2[i] = std::max(dp2[i], c2[x] + 1); } for(int x = n - rk(s[i]) + 1; x <= n; x += (x & -x)) { c1[x] = std::min(c1[x], dp1[i]); c2[x] = std::max(c2[x], dp2[i]); } } return (dp1[n] <= k && k <= dp2[n]); } int main() { std::cin >> n >> k >> T; for(int i = 1; i <= n; ++i) std::cin >> b[0][i]; for(int i = 1; i <= n; ++i) std::cin >> f[i]; for(int i = 1; i <= T; ++i) for(int j = 1; j <= n; ++j) b[i][j] = b[i - 1][f[j]]; std::vector<int> p(T + 1); std::iota(p.begin(), p.end(), 0); std::shuffle(p.begin(), p.end(), rng); ll ans = -2e12; for(int i : p) if(!check(b[i], ans)) { ll l = ans, r = 2e12; while(l <= r) { ll mid = l + (r - l) / 2; if(check(b[i], mid)) ans = mid, r = mid - 1; else l = mid + 1; } } std::cout << ans << "\n"; return 0; }