Topic meaning:
Alice and Bob take turns to take N piles of stones, each pile is S[i], Alice first, each time can take any stone from any pile, or can divide a pile of stones into two small piles. The first to finish wins. (1 ≤ N ≤ 10^6, 1 ≤ S[i] ≤ 2^31 - 1)
Problem solving ideas:
For a given directed acyclic graph, define the Sprague-Grundy function g about each vertex of the graph as follows: g(x)=mex{ g(y) | y is the successor of x}, where g(x ) is sg[x]
For example, in the problem of taking stones, there is a pile of n stones, and only {1, 3, 4} stones can be taken at a time. The one who takes the stones first wins, then what is the SG value of each number?
When sg[0]=0,
n=1, {1} stones can be removed, leaving {0} stones, mex{sg[0]}={0}, so sg[1]=1;
n=2 When , {1} stones can be taken away, the remaining {1} stones, mex{sg[1]}={1}, so sg[2]=0;
when n=3, {1,3} can be taken away There are {2,0} stones remaining, mex{sg[2],sg[0]}={0,0}, so sg[3]=1;
when n=4, {1,3 can be taken away ,4} stones, {3,1,0} remaining, mex{sg[3],sg[1],sg[0]}={1,1,0}, so sg[4]=2;
When n=5, {1,3,4} stones can be taken away, and the remaining {4,2,1} stones, mex{sg[4],sg[2],sg[1]}={2,0 ,1}, so sg[5]=3;
and so on.....
x 0 1 2 3 4 5 6 7 8....
sg[x] 0 1 0 1 2 3 2 0 1... .So, for this question:
sg[0]=0
sg[1]=mex{sg[0] }=1
sg[2]=mex{sg[0],sg[1],sg[1,1] }=mex{0,1,1^1}=2;
sg[3]=mex{sg[0],sg[1],sg[2],sg[1,2]}=mex{0,1,2,1^2}=mex{0,1,2 ,3}=4;
sg[4]=mex{sg[0],sg[1],sg[2],sg[3],sg[1,3],sg[2,2]}=mex{0,1,2, 4,5,0}=3;
..............................................................................
It can be found: sg[4*k+1]=4*k+1,sg[4*k+2]=4*k+2, sg[4*k+3]=4*k+4,sg[ 4*k+4]=4*k+3
sg function table program
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; int main() { int i, j; int sg[1010], mex[1010]; sg [0] = 0, sg [1] = 1; for(i = 2; i <= 1000; i++) { memset(mex, 0, sizeof mex); for(j = 1; j <= i/2; j++) { mex[sg[j]^sg[i - j]] = 1; } for(j = 1; j <= i; j++) { mex[sg[i - j]] = 1; } for(j = 0; ; j++) { if(mex[j] == 0) { sg[i] = j; break; } } } for(i = 0; i <= 100; i++) { printf("sg[%d] : %d\n", i, sg[i]); } return 0; }
#include<stdio.h> using namespace std; int sg(int x){ if(x%4==0) return x-1; if(x%4==3) return x+1; else return x; } int main(){ int t; scanf("%d",&t); while(t--){ int n; scanf("%d",&n); int temp=0; for(int i=0;i<n;i++) { int x; scanf("%d",&x); temp^=sg(x); } if(temp) printf("Alice\n"); else printf("Bob\n"); } return 0; }