zoj 3529 A Game Between Alice and Bob 博弈论
思路:每个数的SG值就是其质因子个数,在进行nim博弈
代码如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<set> 7 #include<vector> 8 #define ll long long 9 #define M 5000005 10 #define inf 1e10 11 #define mod 1000000007 12 using namespace std; 13 int prime[M/3],cnt,sg[M],a[100005]; 14 bool f[M]; 15 void init() 16 { 17 cnt=0; 18 for(int i=2;i<M;i++){ 19 if(!f[i]) prime[cnt++]=i; 20 for(int j=0;j<cnt&&i*prime[j]<M;j++){ 21 f[i*prime[j]]=1; 22 if(i%prime[j]==0) break; 23 } 24 } 25 } 26 int get_sg(int n) 27 { 28 if(sg[n]!=-1) return sg[n]; 29 if(!f[n]) return sg[n]=1; 30 int m=0,nn=n; 31 for(int i=0;i<cnt&&prime[i]*prime[i]<=n;i++){ 32 if(n%prime[i]==0){ 33 m++; 34 n/=prime[i]; 35 while(n%prime[i]==0){ 36 m++; 37 n/=prime[i]; 38 } 39 } 40 } 41 if(n>1) m++; 42 return sg[nn]=m; 43 } 44 int main() 45 { 46 init(); 47 int i,j,k,m,n,ca=0; 48 memset(sg,-1,sizeof(sg)); 49 sg[1]=0; 50 while(scanf("%d",&n)!=EOF){ 51 m=0; 52 for(i=0;i<n;i++){ 53 scanf("%d",&a[i]); 54 m^=get_sg(a[i]); 55 } 56 printf("Test #%d: ",++ca); 57 if(m){ 58 for(i=0;i<n;i++) 59 if((m^sg[a[i]])<sg[a[i]]){ 60 printf("Alice %d\n",i+1); 61 break; 62 } 63 } 64 else puts("Bob"); 65 } 66 return 0; 67 }