Submission #402981

#TimeUsernameProblemLanguageResultExecution timeMemory
402981mjhmjh1104Abduction 2 (JOI17_abduction2)C++14
44 / 100
5049 ms9668 KiB
#include <map> #include <tuple> #include <cstdio> #include <vector> #include <algorithm> using namespace std; int tree_a[131072], tree_b[131072]; vector<tuple<int, int, int>> tv; void interval(int i, int b, int e, int l, int r) { if (r < b || e < l) return; if (l <= b && e <= r) { tv.push_back({ i, b, e }); return; } int m = (b + e) / 2; interval(i * 2 + 1, b, m, l, r); interval(i * 2 + 2, m + 1, e, l, r); } int lower_bound_left_real_a(int i, int b, int e, int v) { if (b == e) return b; int m = (b + e) / 2; if (tree_a[i * 2 + 2] > v) return lower_bound_left_real_a(i * 2 + 2, m + 1, e, v); return lower_bound_left_real_a(i * 2 + 1, b, m, v); } int lower_bound_left_real_b(int i, int b, int e, int v) { if (b == e) return b; int m = (b + e) / 2; if (tree_b[i * 2 + 2] > v) return lower_bound_left_real_b(i * 2 + 2, m + 1, e, v); return lower_bound_left_real_b(i * 2 + 1, b, m, v); } int lower_bound_right_real_a(int i, int b, int e, int v) { if (b == e) return b; int m = (b + e) / 2; if (tree_a[i * 2 + 1] > v) return lower_bound_right_real_a(i * 2 + 1, b, m, v); return lower_bound_right_real_a(i * 2 + 2, m + 1, e, v); } int lower_bound_right_real_b(int i, int b, int e, int v) { if (b == e) return b; int m = (b + e) / 2; if (tree_b[i * 2 + 1] > v) return lower_bound_right_real_b(i * 2 + 1, b, m, v); return lower_bound_right_real_b(i * 2 + 2, m + 1, e, v); } int lower_bound_left_a(int x, int v) { tv.clear(); interval(0, 0, 65535, 0, x); reverse(tv.begin(), tv.end()); for (auto &i: tv) { auto [ a, b, c ] = i; if (tree_a[a] > v) return lower_bound_left_real_a(a, b, c, v); } return -1; } int lower_bound_left_b(int x, int v) { tv.clear(); interval(0, 0, 65535, 0, x); reverse(tv.begin(), tv.end()); for (auto &i: tv) { auto [ a, b, c ] = i; if (tree_b[a] > v) return lower_bound_left_real_b(a, b, c, v); } return -1; } int lower_bound_right_a(int x, int v) { tv.clear(); interval(0, 0, 65535, x, 65535); for (auto &i: tv) { auto [ a, b, c ] = i; if (tree_a[a] > v) return lower_bound_right_real_a(a, b, c, v); } return 65536; } int lower_bound_right_b(int x, int v) { tv.clear(); interval(0, 0, 65535, x, 65535); for (auto &i: tv) { auto [ a, b, c ] = i; if (tree_b[a] > v) return lower_bound_right_real_b(a, b, c, v); } return 65536; } int h, w, q; int a[50006], b[50006]; pair<int, bool> lt[100006]; vector<pair<int, long long>> v[100006]; vector<int> compress; int main() { scanf("%d%d%d", &w, &h, &q); for (int i = 0; i < w; i++) scanf("%d", a + i); for (int i = 0; i < h; i++) scanf("%d", b + i); for (int i = 0; i < w; i++) compress.push_back(a[i]); for (int i = 0; i < h; i++) compress.push_back(b[i]); sort(compress.begin(), compress.end()); for (int i = 0; i < w; i++) a[i] = lower_bound(compress.begin(), compress.end(), a[i]) - compress.begin(); for (int i = 0; i < h; i++) b[i] = lower_bound(compress.begin(), compress.end(), b[i]) - compress.begin(); for (int i = 0; i < w; i++) lt[a[i]] = { i, false }; for (int i = 0; i < h; i++) lt[b[i]] = { i, true }; for (int i = 0; i < w; i++) tree_a[65535 + i] = a[i]; for (int i = 0; i < h; i++) tree_b[65535 + i] = b[i]; for (int i = 65534; i >= 0; i--) { tree_a[i] = max(tree_a[i * 2 + 1], tree_a[i * 2 + 2]); tree_b[i] = max(tree_b[i * 2 + 1], tree_b[i * 2 + 2]); } for (int i = 0; i < q; i++) { int s, t; scanf("%d%d", &t, &s); s--, t--; long long res = 0; if (s > 0) { // up for (int j = 0; j < 100006; j++) v[j].clear(); int it = lower_bound_left_b(s - 1, a[t]); if (it < 0) res = max(res, (long long)s); else { v[b[it]].push_back({ t, s - it }); for (int i = 0; i < h + w; i++) if (!v[i].empty()) { if (!lt[i].second) { int above = lower_bound_left_b(v[i].front().first, a[lt[i].first]), bottom = lower_bound_right_b(v[i].front().first, a[lt[i].first]); if (above < 0) for (auto &j: v[i]) res = max(res, j.second + j.first); else { if (!v[b[above]].empty() && lower_bound_left_a(v[b[above]].front().first, b[above]) != lower_bound_left_a(lt[i].first, b[above])) v[b[above]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (j.first - above)); v[b[above]].push_back({ lt[i].first, ret }); } if (bottom >= 65536) for (auto &j: v[i]) res = max(res, j.second + (h - 1 - j.first)); else { if (!v[b[bottom]].empty() && lower_bound_left_a(v[b[bottom]].front().first, b[bottom]) != lower_bound_left_a(lt[i].first, b[bottom])) v[b[bottom]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (bottom - j.first)); v[b[bottom]].push_back({ lt[i].first, ret }); } } else { int left = lower_bound_left_a(v[i].front().first, b[lt[i].first]), right = lower_bound_right_a(v[i].front().first, b[lt[i].first]); if (left < 0) for (auto &j: v[i]) res = max(res, j.second + j.first); else { if (!v[a[left]].empty() && lower_bound_left_b(v[a[left]].front().first, a[left]) != lower_bound_left_b(lt[i].first, a[left])) v[a[left]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (j.first - left)); v[a[left]].push_back({ lt[i].first, ret }); } if (right >= 65536) for (auto &j: v[i]) res = max(res, j.second + (w - 1 - j.first)); else { if (!v[a[right]].empty() && lower_bound_left_b(v[a[right]].front().first, a[right]) != lower_bound_left_b(lt[i].first, a[right])) v[a[right]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (right - j.first)); v[a[right]].push_back({ lt[i].first, ret }); } } } } } if (s < h - 1) { // down for (int j = 0; j < 100006; j++) v[j].clear(); int it = lower_bound_right_b(s + 1, a[t]); if (it >= 65536) res = max(res, (long long)(h - 1 - s)); else { v[b[it]].push_back({ t, it - s }); for (int i = 0; i < h + w; i++) if (!v[i].empty()) { if (!lt[i].second) { int above = lower_bound_left_b(v[i].front().first, a[lt[i].first]), bottom = lower_bound_right_b(v[i].front().first, a[lt[i].first]); if (above < 0) for (auto &j: v[i]) res = max(res, j.second + j.first); else { if (!v[b[above]].empty() && lower_bound_left_a(v[b[above]].front().first, b[above]) != lower_bound_left_a(lt[i].first, b[above])) v[b[above]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (j.first - above)); v[b[above]].push_back({ lt[i].first, ret }); } if (bottom >= 65536) for (auto &j: v[i]) res = max(res, j.second + (h - 1 - j.first)); else { if (!v[b[bottom]].empty() && lower_bound_left_a(v[b[bottom]].front().first, b[bottom]) != lower_bound_left_a(lt[i].first, b[bottom])) v[b[bottom]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (bottom - j.first)); v[b[bottom]].push_back({ lt[i].first, ret }); } } else { int left = lower_bound_left_a(v[i].front().first, b[lt[i].first]), right = lower_bound_right_a(v[i].front().first, b[lt[i].first]); if (left < 0) for (auto &j: v[i]) res = max(res, j.second + j.first); else { if (!v[a[left]].empty() && lower_bound_left_b(v[a[left]].front().first, a[left]) != lower_bound_left_b(lt[i].first, a[left])) v[a[left]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (j.first - left)); v[a[left]].push_back({ lt[i].first, ret }); } if (right >= 65536) for (auto &j: v[i]) res = max(res, j.second + (w - 1 - j.first)); else { if (!v[a[right]].empty() && lower_bound_left_b(v[a[right]].front().first, a[right]) != lower_bound_left_b(lt[i].first, a[right])) v[a[right]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (right - j.first)); v[a[right]].push_back({ lt[i].first, ret }); } } } } } if (t > 0) { // left for (int j = 0; j < 100006; j++) v[j].clear(); int it = lower_bound_left_a(t - 1, b[s]); if (it < 0) res = max(res, (long long)t); else { v[a[it]].push_back({ s, t - it }); for (int i = 0; i < h + w; i++) if (!v[i].empty()) { if (!lt[i].second) { int above = lower_bound_left_b(v[i].front().first, a[lt[i].first]), bottom = lower_bound_right_b(v[i].front().first, a[lt[i].first]); if (above < 0) for (auto &j: v[i]) res = max(res, j.second + j.first); else { if (!v[b[above]].empty() && lower_bound_left_a(v[b[above]].front().first, b[above]) != lower_bound_left_a(lt[i].first, b[above])) v[b[above]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (j.first - above)); v[b[above]].push_back({ lt[i].first, ret }); } if (bottom >= 65536) for (auto &j: v[i]) res = max(res, j.second + (h - 1 - j.first)); else { if (!v[b[bottom]].empty() && lower_bound_left_a(v[b[bottom]].front().first, b[bottom]) != lower_bound_left_a(lt[i].first, b[bottom])) v[b[bottom]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (bottom - j.first)); v[b[bottom]].push_back({ lt[i].first, ret }); } } else { int left = lower_bound_left_a(v[i].front().first, b[lt[i].first]), right = lower_bound_right_a(v[i].front().first, b[lt[i].first]); if (left < 0) for (auto &j: v[i]) res = max(res, j.second + j.first); else { if (!v[a[left]].empty() && lower_bound_left_b(v[a[left]].front().first, a[left]) != lower_bound_left_b(lt[i].first, a[left])) v[a[left]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (j.first - left)); v[a[left]].push_back({ lt[i].first, ret }); } if (right >= 65536) for (auto &j: v[i]) res = max(res, j.second + (w - 1 - j.first)); else { if (!v[a[right]].empty() && lower_bound_left_b(v[a[right]].front().first, a[right]) != lower_bound_left_b(lt[i].first, a[right])) v[a[right]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (right - j.first)); v[a[right]].push_back({ lt[i].first, ret }); } } } } } if (t < w - 1) { // right for (int j = 0; j < 100006; j++) v[j].clear(); int it = lower_bound_right_a(t + 1, b[s]); if (it >= 65536) res = max(res, (long long)(w - 1 - t)); else { v[a[it]].push_back({ s, it - t }); for (int i = 0; i < h + w; i++) if (!v[i].empty()) { if (!lt[i].second) { int above = lower_bound_left_b(v[i].front().first, a[lt[i].first]), bottom = lower_bound_right_b(v[i].front().first, a[lt[i].first]); if (above < 0) for (auto &j: v[i]) res = max(res, j.second + j.first); else { if (!v[b[above]].empty() && lower_bound_left_a(v[b[above]].front().first, b[above]) != lower_bound_left_a(lt[i].first, b[above])) v[b[above]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (j.first - above)); v[b[above]].push_back({ lt[i].first, ret }); } if (bottom >= 65536) for (auto &j: v[i]) res = max(res, j.second + (h - 1 - j.first)); else { if (!v[b[bottom]].empty() && lower_bound_left_a(v[b[bottom]].front().first, b[bottom]) != lower_bound_left_a(lt[i].first, b[bottom])) v[b[bottom]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (bottom - j.first)); v[b[bottom]].push_back({ lt[i].first, ret }); } } else { int left = lower_bound_left_a(v[i].front().first, b[lt[i].first]), right = lower_bound_right_a(v[i].front().first, b[lt[i].first]); if (left < 0) for (auto &j: v[i]) res = max(res, j.second + j.first); else { if (!v[a[left]].empty() && lower_bound_left_b(v[a[left]].front().first, a[left]) != lower_bound_left_b(lt[i].first, a[left])) v[a[left]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (j.first - left)); v[a[left]].push_back({ lt[i].first, ret }); } if (right >= 65536) for (auto &j: v[i]) res = max(res, j.second + (w - 1 - j.first)); else { if (!v[a[right]].empty() && lower_bound_left_b(v[a[right]].front().first, a[right]) != lower_bound_left_b(lt[i].first, a[right])) v[a[right]].clear(); long long ret = 0; for (auto &j: v[i]) ret = max(ret, j.second + (right - j.first)); v[a[right]].push_back({ lt[i].first, ret }); } } } } } printf("%lld\n", res); } }

Compilation message (stderr)

abduction2.cpp: In function 'int lower_bound_left_a(int, int)':
abduction2.cpp:55:14: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   55 |         auto [ a, b, c ] = i;
      |              ^
abduction2.cpp: In function 'int lower_bound_left_b(int, int)':
abduction2.cpp:66:14: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   66 |         auto [ a, b, c ] = i;
      |              ^
abduction2.cpp: In function 'int lower_bound_right_a(int, int)':
abduction2.cpp:76:14: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   76 |         auto [ a, b, c ] = i;
      |              ^
abduction2.cpp: In function 'int lower_bound_right_b(int, int)':
abduction2.cpp:86:14: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   86 |         auto [ a, b, c ] = i;
      |              ^
abduction2.cpp: In function 'int main()':
abduction2.cpp:99:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   99 |     scanf("%d%d%d", &w, &h, &q);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~
abduction2.cpp:100:38: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  100 |     for (int i = 0; i < w; i++) scanf("%d", a + i);
      |                                 ~~~~~^~~~~~~~~~~~~
abduction2.cpp:101:38: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  101 |     for (int i = 0; i < h; i++) scanf("%d", b + i);
      |                                 ~~~~~^~~~~~~~~~~~~
abduction2.cpp:117:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  117 |         scanf("%d%d", &t, &s);
      |         ~~~~~^~~~~~~~~~~~~~~~
#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...