Submission #1257143

#TimeUsernameProblemLanguageResultExecution timeMemory
1257143efegMeteors (POI11_met)C++20
74 / 100
6094 ms58204 KiB
#include <bits/stdc++.h> using namespace std; #define int long long #define F first #define S second #define pb push_back #define endl '\n' #define all(v) v.begin(),v.end() typedef vector<int> vi; typedef tuple<int,int,int> iii; typedef vector<vi> vvi; typedef vector<iii> viii; struct SegmentTree{ int n; vi tree, lazy; SegmentTree(int _n){ n = _n; tree.assign(4*n + 5, 0); lazy.assign(4*n + 5, 0); } void push(int node,int s,int e){ if (lazy[node] == 0) return; tree[node] += lazy[node] * (e - s + 1); if (s != e){ lazy[node*2] += lazy[node]; lazy[node*2+1] += lazy[node]; } lazy[node] = 0; } void update(int node,int s,int e,int l,int r,int val){ push(node,s,e); if (s > e || r < s || e < l) return; if (l <= s && e <= r){ lazy[node] += val; push(node,s,e); return; } int m = (s+e)/2; update(node*2,s,m,l,r,val); update(node*2+1,m+1,e,l,r,val); tree[node] = tree[node*2] + tree[node*2+1]; } int query(int node,int s,int e,int x){ push(node,s,e); if (s > e || x < s || e < x) return 0; if (s == e && s == x) return tree[node]; int m = (s+e)/2; return query(node*2,s,m,x) + query(node*2+1,m+1,e,x); } }; int n, m, k; vi sector; vi meteors; viii queries; vvi devlet; int32_t main(){ ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> m; sector.assign(m, 0); devlet.assign(n, vi()); for (int i = 0; i < m; ++i){ cin >> sector[i]; sector[i]--; devlet[ sector[i] ].pb(i); } meteors.assign(n, 0); for (int i = 0; i < n; ++i) cin >> meteors[i]; cin >> k; queries.resize(k+1); for (int i = 1; i <= k; ++i){ int l,r,x; cin >> l >> r >> x; queries[i] = make_tuple(l-1, r-1, x); } // parallel binary search boundaries: [1, k+1], answer k+1 means "NIE" vi left(n, 1), right(n, k+1); // number of iterations needed = ceil(log2(k+1)) int LOG = 0; while ((1LL << LOG) <= k) ++LOG; for (int iter = 0; iter < LOG; ++iter){ SegmentTree tree(m); vector<vi> check(k+2); // check[t] -> list of states testing mid == t for (int i = 0; i < n; ++i){ if (left[i] <= right[i] - 1){ int mid = (left[i] + right[i]) / 2; check[mid].pb(i); } } // apply queries incrementally for times 1..k for (int t = 1; t <= k; ++t){ int a,b,val; tie(a,b,val) = queries[t]; if (a <= b){ tree.update(1, 0, m-1, a, b, val); // FIX: include a==b (single sector) } else { // wrap-around tree.update(1, 0, m-1, a, m-1, val); tree.update(1, 0, m-1, 0, b, val); } for (int state : check[t]){ long long sum = 0; for (int sec : devlet[state]){ sum += tree.query(1, 0, m-1, sec); if (sum >= meteors[state]) break; // small micro-optimization } if (sum >= meteors[state]){ right[state] = t; } else { left[state] = t + 1; } } } } for (int i = 0; i < n; ++i){ if (left[i] == k+1) cout << "NIE\n"; else cout << left[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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...