Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Focus on what values a single position can eventually become. Copying only goes left, so position can only receive information from positions .
If you first set , then repeatedly copy left, the value can be moved into every position . Also, the original can be moved left the same way.
So the best possible value at position is the maximum among all original values in the suffix from both arrays:
There is no hidden conflict between positions. To make , pick some source position with that value, prepare that source if needed, and copy it left until it reaches . Do this independently for every queried position; operations outside the segment can be sacrificed. They are not precious, despite what your inner overthinker says.
After computing from right to left, each query is just Build prefix sums over and answer in .
The operation direction is the whole problem.
You can replace by , so values can only travel from right to left. Also, at any position , you may inject the value by setting .
That means position can eventually receive:
So position can become any value from
Therefore the best value possible at position is
Now comes the part where it is easy to invent fake constraints. You might worry that choosing the best value for one position breaks another position. It does not matter. For a query , we only care about the final values inside that segment, and we are allowed any number of operations. To set a specific position to its best value, choose a source containing that best value, set first if the source is from , then copy left along . This may overwrite positions on the path, but those positions can be fixed later by their own operations. Process positions from left to right if you want a concrete construction: fixing a larger index later is not affected by operations ending farther left. No conflict, no drama.
So every query asks for
We can compute in one right-to-left pass. Let
then .
After that, build prefix sums:
Each query answer is
Edge cases are boring in the best way:
long long anyway. Cheap insurance.Complexity per test case is
time and
memory.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n, q;
cin >> n >> q;
vector<int> a(n + 1), b(n + 1);
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
vector<ll> pref(n + 1, 0);
int best = 0;
for (int i = n; i >= 1; i--) {
best = max({best, a[i], b[i]});
pref[i] = best;
}
for (int i = 1; i <= n; i++) {
pref[i] += pref[i - 1];
}
for (int qi = 0; qi < q; qi++) {
int l, r;
cin >> l >> r;
if (qi) cout << ' ';
cout << pref[r] - pref[l - 1];
}
cout << '\n';
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n, q;
cin >> n >> q;
vector<int> a(n + 1), b(n + 1);
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
vector<ll> pref(n + 1, 0);
int best = 0;
for (int i = n; i >= 1; i--) {
best = max({best, a[i], b[i]});
pref[i] = best;
}
for (int i = 1; i <= n; i++) {
pref[i] += pref[i - 1];
}
for (int qi = 0; qi < q; qi++) {
int l, r;
cin >> l >> r;
if (qi) cout << ' ';
cout << pref[r] - pref[l - 1];
}
cout << '\n';
}
return 0;
}