Balkan OI 2018 - Election
Authors: Andi Qu, Benjamin Qi
Method 1 (Offline)
Consider the greedy strategy: iterate from left to right and change T
s to
satisfy the increasing condition, then do the same from right to left.
We can solve this problem offline by simulating this process.
https://oj.uz/submission/61836
This section is not complete.
Method 2 (Online)
A simpler case
Consider the case where we only care about counting votes from left to right.
Let a C
vote count as and a T
vote count as in an array .
The answer to a query on the range is simply the maximum prefix sum in that range. (i.e. The largest )
If we count votes from right to left though, the answer is the maximum suffix sum instead.
We can use a segment tree to answer both of these types of queries efficiently.
Combining values
It would be really convenient if we could just calculate the maximum prefix and suffix sums and add them. However, we would count some nullified votes twice if we do this.
In each node of the segment tree that stores information about the range we store the following information:
- The maximum prefix sum in the range . (Let this be )
- The maximum suffix sum in the range . (Let this be )
- The total sum of the range. (Let this be )
- The answer to a query on the range . (Let this be )
When we combine two nodes (left child) and (right child) to make node ,
Finding is a bit more tricky though. We will show that it is equal to
For a range of length , this calculates
Claim 1: This is a lower bound on the answer.
We can say that the increasing condition must hold for the first votes and the decreasing condition must hold for the rest of the votes in the range.
Claim 2: This lower bound can be attained.
Consider the greedy strategy mentioned in method 1. Then equality holds when we
set equal to one less than the position of the leftmost T
removed when
doing the right to left iteration.
Therefore, this is a lower bound and it can be attained.
The final complexity of this algorithm is .
Implementation
#include <bits/stdc++.h>#define FOR(i, x, y) for (int i = x; i < y; i++)typedef long long ll;using namespace std;struct Node {int l_max, r_max, tot, ans;Node operator+(Node b) {Node ret;
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!