Submission #978224

#TimeUsernameProblemLanguageResultExecution timeMemory
978224model_codeTower (JOI24_tower)C++17
100 / 100
1223 ms116128 KiB
#include <iostream> #include <vector> #include <algorithm> const long long INF = 3000000000000000000; const int INF2 = 1000000; struct lazy_segment_tree{ int N; std::vector<int> ST; std::vector<int> lazy; lazy_segment_tree(int N2){ N = 1; while (N < N2){ N *= 2; } ST = std::vector<int>(N * 2 - 1, INF2); lazy = std::vector<int>(N * 2 - 1, -1); } void push(int i, int l, int r){ if (lazy[i] != -1){ if (i < N - 1){ lazy[i * 2 + 1] = lazy[i]; lazy[i * 2 + 2] = lazy[i]; } if (lazy[i] == 0){ ST[i] = INF2; } if (lazy[i] == 1){ ST[i] = l; } lazy[i] = -1; } } void range_update(int L, int R, int x, int i, int l, int r){ push(i, l, r); if (r <= L || R <= l){ return; } else if (L <= l && r <= R){ lazy[i] = x; push(i, l, r); } else { int m = (l + r) / 2; range_update(L, R, x, i * 2 + 1, l, m); range_update(L, R, x, i * 2 + 2, m, r); ST[i] = std::min(ST[i * 2 + 1], ST[i * 2 + 2]); } } void range_update(int L, int R, int x){ range_update(L, R, x, 0, 0, N); } int query(int L, int R, int i, int l, int r){ push(i, l, r); if (r <= L || R <= l){ return INF2; } else if (L <= l && r <= R){ return ST[i]; } else { int m = (l + r) / 2; return std::min(query(L, R, i * 2 + 1, l, m), query(L, R, i * 2 + 2, m, r)); } } int query(int L, int R){ return query(L, R, 0, 0, N); } bool operator [](int k){ return query(k, k + 1) != INF2; } }; int main(){ std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); int N, Q; std::cin >> N >> Q; long long D, A, B; std::cin >> D >> A >> B; B -= A * D; std::vector<long long> L(N), R(N); for (int i = 0; i < N; i++){ std::cin >> L[i] >> R[i]; R[i]++; } std::vector<long long> X(Q); for (int i = 0; i < Q; i++){ std::cin >> X[i]; } std::vector<long long> x, y; x.push_back(0); y.push_back(0); for (int i = 0; i < N; i++){ x.push_back(L[i] / D); x.push_back(L[i] / D + 1); x.push_back(R[i] / D); x.push_back(R[i] / D + 1); x.push_back(R[i] / D + 2); y.push_back(L[i] % D); y.push_back(R[i] % D); } for (int i = 0; i < Q; i++){ x.push_back(X[i] / D); y.push_back(X[i] % D); } std::sort(x.begin(), x.end()); x.erase(std::unique(x.begin(), x.end()), x.end()); std::sort(y.begin(), y.end()); y.erase(std::unique(y.begin(), y.end()), y.end()); int H = x.size(); int W = y.size(); std::vector<int> lx(N), ly(N), rx(N), ry(N); for (int i = 0; i < N; i++){ lx[i] = std::lower_bound(x.begin(), x.end(), L[i] / D) - x.begin(); ly[i] = std::lower_bound(y.begin(), y.end(), L[i] % D) - y.begin(); rx[i] = std::lower_bound(x.begin(), x.end(), R[i] / D) - x.begin(); ry[i] = std::lower_bound(y.begin(), y.end(), R[i] % D) - y.begin(); } std::vector<long long> ans(Q, 0); std::vector<int> qx(Q), qy(Q); for (int i = 0; i < Q; i++){ qx[i] = std::lower_bound(x.begin(), x.end(), X[i] / D) - x.begin(); qy[i] = std::lower_bound(y.begin(), y.end(), X[i] % D) - y.begin(); ans[i] = A * X[i] + std::min(B, (long long) 0) * (X[i] / D - qx[i]); } std::vector<std::vector<int>> ng(H); for (int i = 0; i < N; i++){ ng[lx[i]].push_back(ly[i]); for (int j = lx[i]; j < rx[i]; j++){ ng[j].push_back(W); ng[j + 1].push_back(0); } if (ry[i] == 0){ ng[rx[i]].pop_back(); } else { ng[rx[i]].push_back(ry[i]); } } std::vector<std::vector<int>> ok(H); for (int i = 0; i < H; i++){ ok[i].push_back(0); for (int j : ng[i]){ if (j == 0){ ok[i].pop_back(); } else { ok[i].push_back(j); } } if (ok[i].back() == W){ ok[i].pop_back(); } else { ok[i].push_back(W); } } std::vector<std::vector<int>> query(H); for (int i = 0; i < Q; i++){ query[qx[i]].push_back(i); } lazy_segment_tree dp(W); dp.range_update(0, 1, 1); int a = -1, b = 0; for (int i = 0; i < H; i++){ if (i > 0){ bool pr = dp[W - 1]; int cnt_ng = ng[i].size(); for (int j = 0; j < cnt_ng; j += 2){ dp.range_update(ng[i][j], ng[i][j + 1], 0); } if (!ok[i].empty()){ if (ok[i][0] == 0){ if (pr){ if (!dp[0] || B > 0){ b = std::max(b, 1); } dp.range_update(0, 1, 1); } } } } int cnt_ok = ok[i].size(); for (int j = 0; j < cnt_ok; j += 2){ int idx = dp.query(ok[i][j], ok[i][j + 1]); if (idx != INF2){ if (idx < b && b < ok[i][j + 1]){ int next_b = ok[i][j + 1]; if (B < 0){ next_b = dp.query(b, ok[i][j + 1]); if (next_b == INF2){ next_b = ok[i][j + 1]; } } b = next_b; } dp.range_update(idx, ok[i][j + 1], 1); } } for (int j : query[i]){ if (!dp[qy[j]]){ ans[j] = -1; } else { ans[j] += (qy[j] < b ? B * a : B * (a + 1)) + B * i; } } if (b == W){ b = 0; a--; } } for (int i = 0; i < Q; i++){ std::cout << ans[i] << '\n'; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...