Luogu P3235 [HNOI2014] Jiangnan music (Multi-SG), p3235hnoi2014
Description
Mr. A is A real avid turn-based game player. After winning many world-class awards for turn-based games, Mr. A suddenly remembered A turn-based game he played in Jiangnan when he was A child.
The rule of the game is as follows: first, a number F is given, and then the game system will generate a group of T games. Each game group contains N piles of stones, and Mr. A and his opponent take turns to operate. During each operation, the operator selects a positive integer M not less than 2 (M is selected by the operator and can be different during each operation ), then, divide any pile of stones not less than F into M piles, in addition, it satisfies the needs of the M-heap stones that have the largest number of stones to more than one pile with the least number of stones, after selecting M and a pile of stones, the split state is fixed ). When a player cannot operate, that is, when the number of each pile of stones is strictly less than F, he will lose. (Supplement: first hand from N heap stone select a pile of number not less than F of the stones into M heap, at this time a total of N + M-1) Heap stone, next small A from the N + M-1 heap stones to select A pile of stones not less than F, and so on.
Mr. A was A handsome boy from an early age. He invited his opponent as A pioneer. Now Mr. A wants to know who can win A game in the face of A given set of games and his opponent is as smart as he is?
Input/Output Format
Input Format:
The first line of the input contains two positive integers T and F, indicating the number of game groups and the given number. In the next T row, the first N in each row indicates the number of stones in the initial state of the game group. The next N integers indicate the numbers of these N stones.
Output Format:
The output line contains T numbers of 0 or 1 separated by spaces. 0 indicates that A small A (the latter) will win, and 1 indicates the opponent of A small A (the first hand) yes.
Input and Output sample input sample #1: Copy
4 31 11 21 31 5
Output example #1: Copy
0 0 1 1
Description
For 100% of the data, T <100, N <100, F <100000, the number of stones per heap <100000.
All the preceding numbers are positive integers.
Black question is hard to provoke ..
Brute force is relatively easy to write, and you can directly enumerate $ m $
During Heap splitting, $ \ frac {n} {I} $ heap is required. $ n \ mod I $ stones are left, which are evenly distributed back.
In this way, the size of $ n \ mod I $ heap is $ \ frac {n} {I} + 1 $.
There are $ I-n \ mod I $ heap size: $ \ frac {n} {I} $
However, $ O (n * m) $ cannot be used.
It is not difficult to find that $ \ frac {n} {I} $ only has a value of $ \ sqrt {n} $. Observe and find that (God TM can observe ), the contribution of each value to the answer is only $ I $ and $ I + 1 $.
Then let's just calculate the brute force.
// Luogu-judger-enable-o2 # include <cstdio> # include <cstring> # include <algorithm> const int MAXN = 100001; inline int read () {char c = getchar (); int x = 0, f = 1; while (c <'0' | c> '9') {if (c = '-') f =-1; c = getchar () ;}while (c >='0' & c <= '9') {x = x * 10 + c-'0 '; c = getchar ();} return x * f;} int N, S [MAXN], SG [MAXN]; // The game can be viewed as an int a [MAXN], F; int GetSG (const int now) {if (~ SG [now]) return SG [now]; if (now <F) return SG [now] = 0; SG [now] = 0; for (int I = 2; I <= now; I = now/(now/I) + 1) // enumerate each value {for (int j = I; j <= std :: min (I + 1, now); j ++) // observed that there are only two different contributions {int ans = 0; if (now % j) & 1) ans = ans ^ GetSG (now/j + 1); if (j-now % j) & 1) ans = ans ^ GetSG (now/j ); S [ans] = now ;}while (S [SG [now] = now) SG [now] ++; // here is a small optimization return SG [now];} int main () {# ifdef WIN32 freopen (". in "," r ", stdin); # else # endif int QWQ = read (); F = read (); memset (SG,-1, sizeof (SG )); while (QWQ --) {int N = read (); for (int I = 1; I <= N; I ++) a [I] = read (); int ans = 0; for (int I = 1; I <= N; I ++) ans = ans ^ GetSG (a [I]); if (ans = 0) printf ("0"); else printf ("1");} return 0 ;}