Bessie and Elsie are playing a game with NN (1≤N≤1051≤N≤105) piles of stones, where the ii-th pile has aiai stones for each 1≤i≤N1≤i≤N (1≤ai≤1061≤ai≤106). The two cows alternate turns, with Bessie going first.
The first cow who is unable to remove stones on her turn loses.
Compute the number of ways Bessie can remove stones on her first turn in order to guarantee a win (meaning that there exists a strategy such that Bessie wins regardless of what choices Elsie makes). Two ways of removing stones are considered to be different if they remove a different number of stones or they remove stones from different piles.
The first line contains NN.The second line contains NN space-separated integers a1,…,aNa1,…,aN.
Print the number of ways Bessie can remove stones on her first turn in order to guarantee a win.Note that the large size of integers involved in this problem may require the use of 64-bit integer data types (e.g., a "long long" in C/C++).
1 7
4
Bessie wins if she removes 44, 55, 66, or 77 stones from the only pile. Then the game terminates immediately.
6 3 2 3 2 3 1
8
Bessie wins if she removes 22 or 33 stones from any pile. Then the two players will alternate turns removing the same number of stones, with Bessie making the last move.
Problem credits: Benjamin Qi
[/hide]
(Analysis by Benjamin Qi)
We can think of a valid move in the game as follows:
We claim that a state in the game is losing for the first player iff for each x≥1x≥1, the number of piles of size xx is even. In this case, the second player can win by simply mirroring the moves of the first player.
In all other states, let xx the maximum pile size such that the number of piles of size exactly xx is odd. Then the first player wins if she removes that pile.
Now suppose that Bessie removes xx stones from some pile on her first turn. Then we need to count the number of integers among the sequence Sx=[⌊a1x⌋,⌊a2x⌋,⌊a3x⌋,…,⌊anx⌋]Sx=[⌊a1x⌋,⌊a2x⌋,⌊a3x⌋,…,⌊anx⌋] such that when decreased by one, every positive integer in the sequence occurs an even number of times (ignoring zero).
So Bessie wins if she picks t>0t>0 such that
For each xx and tt, the number of occurrences of tt in SxSx is equal to the number of integers in the input sequence that are in the range [xt,x(t+1)−1][xt,x(t+1)−1]. For a fixed xx, we can compute this quantity for all relevant tt in O(maxaix)O(maxaix) time using prefix sums. After this, it's just a matter of checking which numbers appear an odd number of times in SxSx and updating the answer accordingly.
Time Complexity: O(N+(maxai)log(maxai))O(N+(maxai)log(maxai)).
#include <bits/stdc++.h> using namespace std; int main() { int N; cin >> N; vector<int> A(N); int mx = 0; for (int& t: A) { cin >> t; mx = max(mx,t); } vector<int> cum(mx+1); for (int t: A) ++cum[t]; for (int i = 1; i <= mx; ++i) cum[i] += cum[i-1]; auto getCum = [&](int ind) { // number of elements of A <= ind if (ind > mx) return cum.back(); return cum[ind]; }; long long ans = 0; for (int x = 1; x <= mx; ++x) { vector<int> counts{0}; for (int t = 1; x*t <= mx; ++t) counts.push_back(getCum(x*(t+1)-1)-getCum(x*t-1)); vector<int> odd; for (int t = 1; t < counts.size(); ++t) if (counts[t]&1) odd.push_back(t); if (odd == vector<int>{1} || (odd.size() == 2 && odd[0]+1 == odd[1])) ans += counts[odd.back()]; } cout << ans << "\n"; }
Danny Mittal's Code (somewhat different):
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.StringTokenizer; public class StoneGame { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(in.readLine()); Integer[] piles = new Integer[n + 1]; StringTokenizer tokenizer = new StringTokenizer(in.readLine()); for (int j = 0; j < n; j++) { piles[j] = Integer.parseInt(tokenizer.nextToken()); } piles[n] = 0; Arrays.sort(piles); int[] diffSums = new int[1000001]; int[] indexSums = new int[1000001]; for (int j = n; j >= 1; j -= 2) { diffSums[piles[j]]++; diffSums[piles[j - 1]]--; indexSums[piles[j]] += j; indexSums[piles[j - 1]] -= j; } long answer = 0; for (int k = 1000000; k > 0; k--) { diffSums[k - 1] += diffSums[k]; indexSums[k - 1] += indexSums[k]; int diff = 0; int index = 0; for (int m = k; m <= 1000000; m += k) { diff += diffSums[m]; index += indexSums[m]; } if (diff == 1) { int upper = n; int lower = index; while (upper > lower) { int mid = (upper + lower + 1) / 2; if (piles[mid] / k == piles[index] / k) { lower = mid; } else { upper = mid - 1; } } answer += upper - index + 1; } } System.out.println(answer); } }
[/hide]
翰林课程体验,退费流程快速投诉邮箱: yuxi@linstitute.net 沪ICP备2023009024号-1