sg函数打表。一开始我是这么打的表。天真以为nlogn应该可以。但是跑了很久。。。。
void gsg() {
memset(sg, 0, sizeof(sg));
sg[0]=0;
for (int i = 1; i < 5000024; i++) {
memset(Hash, 0, sizeof(Hash));
for (int j = 1; j*j <= i; j++)
if(i%j==0){
if(j!=1) Hash[sg[j]] =Hash[sg[i/j]]=1;
else if(i!=1) Hash[sg[j]]=1;
}
for(int j=0;;j++)
if (Hash[j] == 0) {
sg[i] = j;
if(j>29) cout<<"1"<<endl;
break;
}
}
}
后面观察了下sg[i],发现就是代表i中有多少个素因子。于是变成这样打表,模拟素数打表的方法
void work(){
sg[0]=sg[1]=0;
for(int i=2;i<5000024;i++){
if(sg[i]==0) sg[i]=1;
for(int j=2*i;j<5000024;j+=i){
if(sg[i]+1>sg[j]) sg[j]=sg[i]+1;
}
}
}
最终代码
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cstdio>
#include <climits>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <map>
#include <sstream>
#include <time.h>
#define INF 0x3f3f3f3f
#define LL long long
#define fora(i,a,n) for(int i=a;i<=n;i++)
#define fors(i,n,a) for(int i=n;i>=a;i--)
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define MAXN 100024
const double eps = 1e-8;
using namespace std;
int sg[5000024];
//int Hash[29];
//int p[5000024];
int a[100024];
int k=1;
void work(){
sg[0]=sg[1]=0;
for(int i=2;i<5000024;i++){
if(sg[i]==0) sg[i]=1;
for(int j=2*i;j<5000024;j+=i){
if(sg[i]+1>sg[j]) sg[j]=sg[i]+1;
}
}
}
//void gsg() {
// memset(sg, 0, sizeof(sg));
// sg[0]=0;
// for (int i = 1; i < 5000024; i++) {
// memset(Hash, 0, sizeof(Hash));
// for (int j = 1; j*j <= i; j++)
// if(i%j==0){
// if(j!=1) Hash[sg[j]] =Hash[sg[i/j]]=1;
// else if(i!=1) Hash[sg[j]]=1;
// }
// for(int j=0;;j++)
// if (Hash[j] == 0) {
// sg[i] = j;
// if(j>29) cout<<"1"<<endl;
// break;
// }
// }
//}
int main() {
#ifdef DID
freopen("in.txt", "r", stdin);
//freopen("out.txt","w",stdout);
clock_t S=clock(),F;
#endif
work();
/*gsg();
for(int i=0;i<5000024;i++)
if(sg[i]!=p[i])
cout<<sg[i]<<" "<<p[i]<<endl;*/
int n;
while (scanf("%d",&n)==1) {
printf("Test #%d: ",k++);
int XOR = 0;
for (int i = 0; i < n; i++)sci(a[i]), XOR ^= sg[a[i]];
if (XOR){
printf("Alice ");
int ans=-1;
fora(i,0,n-1){
for(int j=1;j*j<=a[i];j++)
if(a[i]%j==0){
if(j!=1){
if((XOR^sg[a[i]]^sg[j])==0) {ans=i;break;} //记得加括号,因为==优先级比符号^高。~~
if((XOR^sg[a[i]]^sg[a[i]/j])==0) {ans=i;break;}
}
else if(a[i]!=1)
if((XOR^sg[a[i]]^sg[j])==0) {
ans=i;break;
}
}
if(ans!=-1) break;
}
printf("%d\n",ans+1);
}
else printf("Bob\n");
}
#ifdef DID
F=clock();
printf("时间:%lf\n",double(F-S));
#endif
return 0;
}