Submission #1186994

#TimeUsernameProblemLanguageResultExecution timeMemory
1186994ulvixPilot (NOI19_pilot)C++20
5 / 100
12 ms1608 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); ll n, q; cin >> n >> q; vector<ll> v(n); for (ll i = 0; i < n; i++) cin >> v[i]; // Preprocess segments vector<pair<ll, ll>> segments; // {max_value_in_segment, count_of_subarrays} ll i = 0; while (i < n) { if (i < n && v[i] == LLONG_MAX) { i++; continue; } ll j = i; ll max_val = v[i]; while (j < n && v[j] != LLONG_MAX) { max_val = max(max_val, v[j]); j++; } ll len = j - i; ll count = len * (len + 1) / 2; segments.emplace_back(max_val, count); i = j; } // For this specific problem, we want segments where ALL values < query // So we actually need to process the array differently: // Let's process and track contiguous segments where values are < some threshold // Instead of the above, do this: vector<pair<ll, ll>> segs; // {max_value_in_segment, count_of_subarrays} i = 0; while (i < n) { if (v[i] == -1) { i++; continue; } if (v[i] >= 1e9 + 1) { i++; continue; } if (v[i] < 0) { i++; continue; } if (v[i] != LLONG_MAX) { ll j = i; ll min_value = v[i]; while (j < n && v[j] != LLONG_MAX) { min_value = max(min_value, v[j]); j++; } ll len = j - i; ll cnt = len * (len + 1) / 2; segs.push_back({min_value, cnt}); i = j; } else { i++; } } // Instead of doing the above with undefined values, we’ll use: // Step 1: Find all contiguous segments where values are strictly LESS than a given value vector<pair<ll, ll>> thresholds; // {max_element_in_segment, count_of_subarrays} i = 0; while (i < n) { if (v[i] >= 0) { ll j = i; ll max_elem = v[i]; while (j < n && v[j] >= 0) { max_elem = max(max_elem, v[j]); j++; } ll len = j - i; ll cnt = len * (len + 1) / 2; thresholds.push_back({max_elem, cnt}); i = j; } else { i++; } } // But better: treat values >= threshold as break points vector<pair<ll, ll>> seg_data; // {max_in_segment, count} i = 0; while (i < n) { if (v[i] < 0) { i++; continue; } if (v[i] >= 0) { ll j = i; ll max_v = v[i]; while (j < n && v[j] >= 0) { max_v = max(max_v, v[j]); j++; } ll len = j - i; ll cnt = len * (len + 1) / 2; seg_data.push_back({max_v, cnt}); i = j; } } // More directly: For given array, break into segments where values are all < threshold (to be determined) // Better to preprocess for each segment: record the maximum value (since segment is valid only if all values < a) vector<pair<ll, ll>> segs_final; // {max_value_in_segment, count} i = 0; while (i < n) { if (v[i] < 0) { i++; continue; } ll j = i; ll max_v = v[i]; while (j < n && v[j] >= 0) { max_v = max(max_v, v[j]); j++; } ll len = j - i; ll cnt = len * (len + 1) / 2; segs_final.push_back({max_v, cnt}); i = j; } // Sort segments by max_value in segment sort(segs_final.begin(), segs_final.end()); // Build prefix sum vector<ll> prefix_sum(segs_final.size()); for (size_t i = 0; i < segs_final.size(); i++) { prefix_sum[i] = segs_final[i].second + (i > 0 ? prefix_sum[i - 1] : 0); } // Answer queries in log time while (q--) { ll a; cin >> a; // Find number of segments with max < a auto it = upper_bound(segs_final.begin(), segs_final.end(), make_pair(a - 1, LLONG_MAX)); ll idx = distance(segs_final.begin(), it); ll ans = (idx > 0 ? prefix_sum[idx - 1] : 0); cout << ans << '\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...