The MEX (minimal excludant) operation is defined first, which is an operation applied to a set that represents the smallest non-negative integer that does not belong to this set. such as Mex{0,1,2,4}=3, Mex{2,3,5}=0, mex{}=0.
For a given, forward-free graph, define the Sprague-grundy function g for 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: Take the stone problem, there are 1 heap n stone, at a time can only take {1,3,4} a stone, first take the stone winner, then the number of the SG value?
sg[0]=0,f[]={1,3,4},
X=1, you can take away 1-f{1} stones, the remaining {0}, mex{sg[0]}={0}, so sg[1]=1;
x=2, you can take away 2-f{1} stones, the remaining {1}, mex{sg[1]}={1}, so sg[2]=0;
X=3, you can take away 3-f{1,3} stones, the remaining {2,0}, mex{sg[2],sg[0]}={0,0}, so sg[3]=1;
X=4, you can take away 4-f{1,3,4} stones, the remaining {3,1,0}, mex{sg[3],sg[1],sg[0]}={1,1,0}, so sg[4]=2;
X=5, you can take away 5-f{1,3,4} stones, the remaining {4,2,1}, mex{sg[4],sg[2],sg[1]}={2,0,1}, so sg[5]=3;
And so on .....
x012345678....
SG[X] 010123201....
Calculates the SG value from the 1-n range.
F (the number of steps that can be walked, f[0] indicates how many ways to go)
F[] need to sort from small to large
1. The number of steps can be 1~m continuous integer, directly modulo, SG (x) = x (m+1);
2. The optional step is any step, SG (x) = x;
3. The optional number of steps is a series of discontinuous numbers, calculated with GETSG ()
Template 1 is as follows (SG Chart):
//f[]: The number of stones that can be taken away//sg[]:0~n value of SG function//hash[]:mex{}intF[n],sg[n],hash[n]; voidGETSG (intN) { inti,j; memset (SG,0,sizeof(SG)); for(i=1; i<=n;i++) {memset (hash,0,sizeof(hash)); for(j=1; f[j]<=i;j++) Hash[sg[i-f[j]]]=1; for(j=0; j<=n;j++)//The smallest non-negative integer that is not present in mes{} { if(hash[j]==0) {Sg[i]=J; Break; } } }}View Code
Template 2 is as follows (DFS):
//Note that the S array to sort by from small to large the SG function is initialized to-1 for each collection simply initialize 1 times//N is the size of the set S S[i] is an array of special rules that are definedints[ the],sg[10010],n;intSg_dfs (intx) { inti; if(sg[x]!=-1) returnSg[x]; BOOLvis[ the]; memset (Vis,0,sizeof(VIS)); for(i=0; i<n;i++) { if(x>=S[i]) {Sg_dfs (x-S[i]); Vis[sg[x-s[i]]]=1; } } inte; for(i=0;; i++) if(!Vis[i]) {e=i; Break; } returnsg[x]=e;}View Code
HDU 1848
Test instructions: Take the stone problem, a total of 3 stones, each time only to take the Fibonacci number of stones, first take the stone to win, ask the winner or the next win
- Optional steps are a series of discontinuous numbers, using GETSG (calculation)
- The end result is a result of all SG values that are different or
The AC code is as follows:
#include <stdio.h>#include<string.h>#defineN 1001//f[]: The number of stones that can be taken away//sg[]:0~n value of SG function//hash[]:mex{}intF[n],sg[n],hash[n]; voidGETSG (intN) { inti,j; memset (SG,0,sizeof(SG)); for(i=1; i<=n;i++) {memset (hash,0,sizeof(hash)); for(j=1; f[j]<=i;j++) Hash[sg[i-f[j]]]=1; for(j=0; j<=n;j++)//The smallest non-negative integer that is not present in mes{} { if(hash[j]==0) {Sg[i]=J; Break; } } }}intMain () {inti,m,n,p; f[0]=f[1]=1; for(i=2; i<= -; i++) F[i]=f[i-1]+f[i-2]; GETSG ( +); while(SCANF ("%d%d%d", &m,&n,&p)! =EOF) { if(m==0&&n==0&&p==0) Break; if((sg[m]^sg[n]^sg[p]) = =0) printf ("nacci\n"); Elseprintf ("fibo\n"); } return 0;}View Code
HDU 1536
Test instructions: First enter K to indicate the size of a collection after which the input set represents the number of elements that can only go to this collection for this pair of stones
Then enter an m to indicate the next m-query for this set
After m lines each row input an n means there are n heaps each heap has n1 a stone ask this line to indicate whether the state is win or lose if win input W otherwise l
Idea: for n heap of stones can be divided into n games after the N-game together is good. The AC code is as follows:
#include <stdio.h>#include<string.h>#include<algorithm>using namespacestd;//Note that the S array to sort by from small to large the SG function is initialized to-1 for each collection simply initialize 1 times//N is the size of the set S S[i] is an array of special rules that are definedints[ the],sg[10010],n;intSg_dfs (intx) { inti; if(sg[x]!=-1) returnSg[x]; BOOLvis[ the]; memset (Vis,0,sizeof(VIS)); for(i=0; i<n;i++) { if(x>=S[i]) {Sg_dfs (x-S[i]); Vis[sg[x-s[i]]]=1; } } inte; for(i=0;; i++) if(!Vis[i]) {e=i; Break; } returnsg[x]=e;}intMain () {intI,m,t,num; while(SCANF ("%d", &n) &&N) { for(i=0; i<n;i++) scanf ("%d",&S[i]); memset (SG,-1,sizeof(SG)); Sort (s,s+N); scanf ("%d",&m); while(m--) {scanf ("%d",&t); intans=0; while(t--) {scanf ("%d",&num); Ans^=Sg_dfs (num); } if(ans==0) printf ("L"); Elseprintf ("W"); } printf ("\ n"); } return 0;}View Code
From:http://www.cnblogs.com/frog112111/p/3199780.html
SG function template (GO)