Разбор
Problem Author: | Maksym Shvedchenko |
Prepared by: | Maksym Shvedchenko |
Editorial by: | Maksym Shvedchenko |
Any player must move only to those cells where the value for the other player is greater than the current value.Note that it doesn't work for the last move. Formally:
Chmyaax can move from cell only to a cell such that .
Anton can move from cell only to a cell such that .
Group 3:
Let be the balance with which the game will end if the current balance is , it is Chmyaks' turn, and the piece is in position . Similarly, let be the balance when it is Anton's turn.
For simplicity, let and .
Then . We will calculate the dynamic programming values in decreasing order from larger indices to smaller ones. Specifically:
and
In the second formula, the term appears cause Anton can use magic.
We have states in the dynamic programming where each is recalculated in at most iterations.
Time complexity:
Memory complexity:
Group 4:
In this group, there are many different solutions, but since they do not lead to a complete solution, they will not be described in great detail. We will implement CDQ divide and conquer. We will also maintain a Li-Chao tree or any other data structure. The solution will then take the following form:
void solve(int l,int r){ int m = (l+r)/2; solve(l,m); solve(m+1,r); CHT::init(); vec<int> left; <-- put there all values from left segment vec<int> right; <-- put there all values from right segment sort(left); sort(right); Now 2 pointers CHT::init(); ..... }
That is, after updating the answer with its subsegment (recursively), we will update through the neighboring segment by sorting the elements (thus getting rid of the condition that the next cell must be larger) and simply applying CHT (Convex Hull Trick).
Time complexity:
Memory complexity:
For the full solution we need more observations:
Each game will last a maximum of 2 moves.
signed main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int n; cin >> n; vec<int> a(n); for (int &i: a) cin >> i; vec<int> b(n); for (int &i: b) cin >> i; int best = -a[0] * (n - 1); int maxA = a[0]; for (int i = 1; i < n - 1; i++) { if (b[i] > maxA) chmax(best, -a[0] * i + b[i] * (n - i - 1)); chmax(maxA, a[i]); } cout << best << endl; }