Submission #1308759

#TimeUsernameProblemLanguageResultExecution timeMemory
1308759orzorzorzGift Exchange (JOI24_ho_t4)C++20
10 / 100
27 ms26628 KiB
#include <iostream> #include <vector> #include <algorithm> #include <cmath> using namespace std; const int MAXN = 500005; const int LOGN = 20; int N, Q; int A[MAXN]; int B[MAXN]; int lg2[MAXN]; // ST表定义 // st_max_b_idx[k][i]: 存储区间 [i, i + 2^k - 1] 中 B 值最大的下标 // st_min_b_idx[k][i]: 存储区间 [i, i + 2^k - 1] 中 B 值最小的下标 // st_max_a_val[k][i]: 存储区间 [i, i + 2^k - 1] 中 A 的最大值 // st_min_b_val[k][i]: 存储区间 [i, i + 2^k - 1] 中 B 的最小值 (用于找第二小) int st_max_b_idx[LOGN][MAXN]; int st_min_b_idx[LOGN][MAXN]; int st_max_a_val[LOGN][MAXN]; int st_min_b_val[LOGN][MAXN]; void build_st() { lg2[1] = 0; for (int i = 2; i <= N; i++) lg2[i] = lg2[i / 2] + 1; for (int i = 1; i <= N; i++) { st_max_b_idx[0][i] = i; st_min_b_idx[0][i] = i; st_max_a_val[0][i] = A[i]; st_min_b_val[0][i] = B[i]; } for (int j = 1; j < LOGN; j++) { for (int i = 1; i + (1 << j) - 1 <= N; i++) { // Max B Index int idx1 = st_max_b_idx[j - 1][i]; int idx2 = st_max_b_idx[j - 1][i + (1 << (j - 1))]; if (B[idx1] >= B[idx2]) st_max_b_idx[j][i] = idx1; else st_max_b_idx[j][i] = idx2; // Min B Index idx1 = st_min_b_idx[j - 1][i]; idx2 = st_min_b_idx[j - 1][i + (1 << (j - 1))]; if (B[idx1] <= B[idx2]) st_min_b_idx[j][i] = idx1; else st_min_b_idx[j][i] = idx2; // Max A Value st_max_a_val[j][i] = max(st_max_a_val[j - 1][i], st_max_a_val[j - 1][i + (1 << (j - 1))]); // Min B Value st_min_b_val[j][i] = min(st_min_b_val[j - 1][i], st_min_b_val[j - 1][i + (1 << (j - 1))]); } } } // 查询区间 [L, R] 中 B 最大值的下标 int query_max_b_idx(int L, int R) { int k = lg2[R - L + 1]; int idx1 = st_max_b_idx[k][L]; int idx2 = st_max_b_idx[k][R - (1 << k) + 1]; return (B[idx1] >= B[idx2]) ? idx1 : idx2; } // 查询区间 [L, R] 中 B 最小值的下标 int query_min_b_idx(int L, int R) { int k = lg2[R - L + 1]; int idx1 = st_min_b_idx[k][L]; int idx2 = st_min_b_idx[k][R - (1 << k) + 1]; return (B[idx1] <= B[idx2]) ? idx1 : idx2; } // 查询区间 [L, R] 中 A 的最大值,如果区间不合法返回 -1 int query_max_a_val(int L, int R) { if (L > R) return -1; int k = lg2[R - L + 1]; return max(st_max_a_val[k][L], st_max_a_val[k][R - (1 << k) + 1]); } // 查询区间 [L, R] 中 B 的最小值,如果区间不合法返回 INF int query_min_b_val(int L, int R) { if (L > R) return 2e9; // Infinity int k = lg2[R - L + 1]; return min(st_min_b_val[k][L], st_min_b_val[k][R - (1 << k) + 1]); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); if (!(cin >> N)) return 0; for (int i = 1; i <= N; i++) cin >> A[i]; for (int i = 1; i <= N; i++) cin >> B[i]; build_st(); cin >> Q; while (Q--) { int L, R; cin >> L >> R; // 1. 检查接收瓶颈:Max B 是否能被其他人满足 int idx_max_b = query_max_b_idx(L, R); int max_b_val = B[idx_max_b]; // 在 [L, R] 中除了 idx_max_b 以外找最大的 A int max_a_left = query_max_a_val(L, idx_max_b - 1); int max_a_right = query_max_a_val(idx_max_b + 1, R); int max_a_others = max(max_a_left, max_a_right); if (max_a_others < max_b_val) { cout << "No\n"; continue; } // 2. 检查发送瓶颈:Min B 是否能送给第二小 B 的人 int idx_min_b = query_min_b_idx(L, R); int a_source = A[idx_min_b]; // 在 [L, R] 中除了 idx_min_b 以外找最小的 B (即第二小 B) int min_b_left = query_min_b_val(L, idx_min_b - 1); int min_b_right = query_min_b_val(idx_min_b + 1, R); int second_min_b = min(min_b_left, min_b_right); if (a_source < second_min_b) { cout << "No\n"; continue; } cout << "Yes\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...