Submission #1057384

#TimeUsernameProblemLanguageResultExecution timeMemory
1057384MilosMilutinovicDungeon 3 (JOI21_ho_t5)C++14
100 / 100
843 ms303568 KiB
#include <bits/stdc++.h> using namespace std; const long long inf = (long long) (1e16); const int N = (int) (4e7); int root, tsz, ch[N][2]; pair<long long, long long> st[N]; void Modify(int& x, long long l, long long r, long long ll, long long rr, int a, long long b) { if (!x) { x = ++tsz; } if (ll <= l && r <= rr) { st[x].first += a; st[x].second += b; return; } long long mid = (l + r) >> 1; if (rr <= mid) { Modify(ch[x][0], l, mid, ll, rr, a, b); } else if (ll > mid) { Modify(ch[x][1], mid + 1, r, ll, rr, a, b); } else { Modify(ch[x][0], l, mid, ll, rr, a, b); Modify(ch[x][1], mid + 1, r, ll, rr, a, b); } } long long Query(int x, long long l, long long r, int i) { if (l == r) { return st[x].first * 1LL * i + st[x].second; } long long mid = (l + r) >> 1; if (i <= mid) { return st[x].first * 1LL * i + st[x].second + Query(ch[x][0], l, mid, i); } else { return st[x].first * 1LL * i + st[x].second + Query(ch[x][1], mid + 1, r, i); } } int main() { ios::sync_with_stdio(false); cin.tie(0); int n, m; cin >> n >> m; vector<int> a(n); for (int i = 0; i < n; i++) { cin >> a[i]; } vector<int> b(n); for (int i = 0; i < n; i++) { cin >> b[i]; } vector<int> L(n), R(n); { vector<int> stk; for (int i = 0; i < n; i++) { while (!stk.empty() && b[i] < b[stk.back()]) { stk.pop_back(); } L[i] = stk.empty() ? -1 : stk.back(); stk.push_back(i); } } { vector<int> stk; for (int i = n - 1; i >= 0; i--) { while (!stk.empty() && b[i] <= b[stk.back()]) { stk.pop_back(); } R[i] = stk.empty() ? n : stk.back(); stk.push_back(i); } } vector<long long> pref(n + 1); for (int i = 0; i < n; i++) { pref[i + 1] = pref[i] + a[i]; } vector<int> s(m), t(m), u(m); for (int i = 0; i < m; i++) { cin >> s[i] >> t[i] >> u[i]; --s[i]; --t[i]; --t[i]; } const int LOG = 20; vector<vector<int>> mx(n, vector<int>(LOG)); vector<vector<int>> mn(n, vector<int>(LOG)); for (int i = 0; i < n; i++) { mx[i][0] = a[i]; mn[i][0] = i; } auto Cmp = [&](int i, int j) { return b[i] < b[j] ? i : j; }; for (int j = 1; j < LOG; j++) { for (int i = 0; i + (1 << j) <= n; i++) { mx[i][j] = max(mx[i][j - 1], mx[i + (1 << (j - 1))][j - 1]); mn[i][j] = Cmp(mn[i][j - 1], mn[i + (1 << (j - 1))][j - 1]); } } vector<int> logs(n + 1); for (int i = 2; i <= n; i++) { logs[i] = logs[i >> 1] + 1; } auto GetMax = [&](int l, int r) { int k = logs[r - l + 1]; return max(mx[l][k], mx[r - (1 << k) + 1][k]); }; auto GetMin = [&](int l, int r) { int k = logs[r - l + 1]; return Cmp(mn[l][k], mn[r - (1 << k) + 1][k]); }; vector<vector<array<long long, 4>>> qc(n); for (int i = 0; i < n; i++) { { // after L_i long long d = pref[R[i]] - pref[i]; qc[i].push_back({0, d, b[i], 0}); qc[i].push_back({d + 1, inf, 0, d * b[i]}); if (L[i] != -1) { qc[L[i]].push_back({0, d, -b[i], 0}); qc[L[i]].push_back({d + 1, inf, 0, -d * b[i]}); } } if (L[i] != -1) { // before L_i vector<long long> v; v.push_back(0); v.push_back(inf); v.push_back(pref[R[i]] - pref[i]); v.push_back(pref[i] - pref[L[i]]); v.push_back(pref[R[i]] - pref[L[i]]); sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end()); for (int j = 0; j + 1 < (int) v.size(); j++) { if (v[j] >= pref[R[i]] - pref[L[i]]) { break; } pair<long long, long long> p, q; if (pref[i] + v[j] < pref[R[i]]) { p = {1, pref[i]}; } else { p = {0, pref[R[i]]}; } if (pref[i] > pref[L[i]] + v[j]) { q = {0, pref[i]}; } else { q = {1, pref[L[i]]}; } pair<long long, long long> r; r.first = p.first - q.first; r.second = p.second - q.second; qc[L[i]].push_back({v[j], v[j + 1] - 1, r.first * b[i], r.second * b[i]}); } } } vector<vector<int>> qs(n); vector<long long> res(m); for (int i = 0; i < m; i++) { if (GetMax(s[i], t[i]) > u[i]) { res[i] = -1; continue; } int low = s[i], high = t[i], pos = t[i]; while (low <= high) { int mid = (low + high) >> 1; if (pref[t[i] + 1] - pref[mid] <= u[i]) { pos = mid; high = mid - 1; } else { low = mid + 1; } } pos = GetMin(pos, t[i]); qs[s[i]].push_back(i); qs[pos].push_back(~i); res[i] += (pref[t[i] + 1] - pref[pos]) * 1LL * b[pos]; } for (int i = n - 1; i >= 0; i--) { for (auto& p : qc[i]) { Modify(root, 0, inf, p[0], p[1], p[2], p[3]); } for (int id : qs[i]) { if (id >= 0) { res[id] += Query(root, 0, inf, u[id]); } else { id = ~id; res[id] -= Query(root, 0, inf, u[id]); } } } for (int i = 0; i < m; i++) { cout << res[i] << '\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...