#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |