先打一个sg函数的表,找找规律,发现sg函数可以递归求解
打表代码如下
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=1e5+7; bool vis[N]; int sg[N]; int k; void init() { memset(sg,0,sizeof(sg)); memset(vis,false,sizeof(vis)); sg[0]=0,sg[1]=0; for(int i=2;i<=80;i++) { memset(vis,0,sizeof(vis)); for(int j=(i+k-1)/k;j<i;j++) vis[sg[j]]=true; for(int j=0;j<=80;j++) if(vis[j]==false) { sg[i]=j; break; } } } int main() { ios::sync_with_stdio(false); while(cin>>k) { init(); for(int i=1;i<=80;i++) { printf("sg[%3d]=%3d%c",i,sg[i],i%k==0? '\n':' '); } puts(""); puts(""); } }
得到的一个结果
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
k=4 sg[ 1]= 0 sg[ 2]= 1 sg[ 3]= 2 sg[ 4]= 3 sg[ 5]= 0 sg[ 6]= 4 sg[ 7]= 5 sg[ 8]= 6 sg[ 9]= 1 sg[ 10]= 7 sg[ 11]= 8 sg[ 12]= 9 sg[ 13]= 2 sg[ 14]= 10 sg[ 15]= 11 sg[ 16]= 12 sg[ 17]= 3 sg[ 18]= 13 sg[ 19]= 14 sg[ 20]= 15 sg[ 21]= 0 sg[ 22]= 16 sg[ 23]= 17 sg[ 24]= 18 sg[ 25]= 4 sg[ 26]= 19 sg[ 27]= 20 sg[ 28]= 21 sg[ 29]= 5 sg[ 30]= 22 sg[ 31]= 23 sg[ 32]= 24 sg[ 33]= 6 sg[ 34]= 25 sg[ 35]= 26 sg[ 36]= 27 sg[ 37]= 1 sg[ 38]= 28 sg[ 39]= 29 sg[ 40]= 30 sg[ 41]= 7 sg[ 42]= 31 sg[ 43]= 32 sg[ 44]= 33 sg[ 45]= 8 sg[ 46]= 34 sg[ 47]= 35 sg[ 48]= 36 sg[ 49]= 9 sg[ 50]= 37 sg[ 51]= 38 sg[ 52]= 39 sg[ 53]= 2 sg[ 54]= 40 sg[ 55]= 41 sg[ 56]= 42 sg[ 57]= 10 sg[ 58]= 43 sg[ 59]= 44 sg[ 60]= 45 sg[ 61]= 11 sg[ 62]= 46 sg[ 63]= 47 sg[ 64]= 48 sg[ 65]= 12 sg[ 66]= 49 sg[ 67]= 50 sg[ 68]= 51 sg[ 69]= 3 sg[ 70]= 52 sg[ 71]= 53 sg[ 72]= 54 sg[ 73]= 13 sg[ 74]= 55 sg[ 75]= 56 sg[ 76]= 57 sg[ 77]= 14 sg[ 78]= 58 sg[ 79]= 59 sg[ 80]= 60
当然k可以改来改去地试
再之后,如果异或和不为0,要特殊处理下,也是根据打表的规律,具体方法见代码
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=1e5+7; LL k; int n; LL a[N]; LL sg(LL x) { if(x==1||x==0) return 0; if(x%k!=1) return x-(x+k-1)/k; return sg(x/k); } int main() { while(~scanf("%d%lld",&n,&k)) { LL ans=0; for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); ans^=sg(a[i]); } // cout<<ans<<endl; if(ans) { int pos; LL y; for(int i=1;i<=n;i++) { LL sgx=sg(a[i]),t=sgx^ans; pos=i; y=t+(t+k-2)/(k-1); // cout<<y<<' '<<(a[i]+k-1)/k<<endl; while(1) { if(y>=a[i]) break; if(y<a[i]&&y>=(a[i]+k-1)/k) { printf("Alice %d %lld\n",pos,y); return 0; } y=y*k+1; } } printf("Alice %d %lld\n",pos,y); } else puts("Bob"); } }