제출 #1186610

#제출 시각아이디문제언어결과실행 시간메모리
1186610zircon새로운 문제 (POI11_met)C++20
100 / 100
5188 ms49456 KiB
#include <iostream> #include <vector> #include <map> #include <algorithm> using namespace std; // Class to handle range updates and point queries for meteor samples struct SegmentTree { vector<long long> tree, lazy; int size; SegmentTree(int n) { size = 1; while (size < n) size *= 2; tree.resize(2 * size, 0); lazy.resize(2 * size, 0); } void push(int x, int lx, int rx) { if (lazy[x] == 0) return; tree[x] += lazy[x]; if (rx - lx > 1) { lazy[2 * x + 1] += lazy[x]; lazy[2 * x + 2] += lazy[x]; } lazy[x] = 0; } void update(int l, int r, long long v, int x, int lx, int rx) { push(x, lx, rx); if (lx >= r || rx <= l) return; if (lx >= l && rx <= r) { lazy[x] += v; push(x, lx, rx); return; } int mid = (lx + rx) / 2; update(l, r, v, 2 * x + 1, lx, mid); update(l, r, v, 2 * x + 2, mid, rx); tree[x] = tree[2 * x + 1] + tree[2 * x + 2]; } void update(int l, int r, long long v) { update(l, r, v, 0, 0, size); } long long get(int i, int x, int lx, int rx) { push(x, lx, rx); if (rx - lx == 1) return tree[x]; int mid = (lx + rx) / 2; if (i < mid) return get(i, 2 * x + 1, lx, mid); else return get(i, 2 * x + 2, mid, rx); } long long get(int i) { return get(i, 0, 0, size); } }; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector<int> owner(m + 1); for (int i = 1; i <= m; i++) { cin >> owner[i]; } vector<long long> required(n + 1); vector<vector<int>> state_sectors(n + 1); for (int i = 1; i <= n; i++) { cin >> required[i]; } // Map sectors to states (0-indexed for segment tree) for (int i = 1; i <= m; i++) { state_sectors[owner[i]].push_back(i - 1); } int k; cin >> k; vector<tuple<int, int, int>> meteors(k); for (int i = 0; i < k; i++) { int l, r, a; cin >> l >> r >> a; meteors[i] = {l, r, a}; } // Binary search ranges for each state vector<int> low(n + 1, 0), high(n + 1, k + 1); while (true) { // Group states by their midpoints map<int, vector<int>> mid_states; bool any_active = false; for (int state = 1; state <= n; state++) { if (low[state] + 1 < high[state]) { any_active = true; int mid = (low[state] + high[state]) / 2; mid_states[mid].push_back(state); } } if (!any_active) break; // Process meteor showers incrementally SegmentTree st(m); int last_processed = 0; for (auto &[mid, states] : mid_states) { // Process all meteor showers between last_processed and mid for (int i = last_processed; i < mid; i++) { auto [l, r, a] = meteors[i]; l--; r--; // Convert to 0-indexed // Handle circular range if (l <= r) { st.update(l, r + 1, a); } else { st.update(l, m, a); st.update(0, r + 1, a); } } last_processed = mid; // Check each state with this midpoint for (int state : states) { // Check if state has enough samples long long total = 0; bool enough = false; for (int sector : state_sectors[state]) { total += st.get(sector); if (total >= required[state]) { enough = true; break; } } if (enough) { high[state] = mid; } else { low[state] = mid; } } } } // Output results for (int i = 1; i <= n; i++) { if (high[i] <= k) cout << high[i] << "\n"; else cout << "NIE\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...