4600: [Sdoi2016]硬幣遊戲
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 7 Solved: 5
[Submit][Status][Discuss]
首先我們可以發現,每個數的形式都是這樣的:
如果我們建立一個二維的座標系,橫座標表示
這樣我們令
有一個問題就是在一個後繼狀態中會被翻的所有的點得
其實這兩個是一個問題,就是這個點和它的後繼點是否是獨立的。
其實是獨立的。我們可以看求
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
bool flag[500];
int T,n,maxq,SG[20][20];
inline void solve2(){
int i,j,p,q,k,x=0,y=0,o;
o=n;while(o>=2) ++x,o/=2;
o=n;while(o>=3) ++y,o/=3;
memset(SG,0,sizeof(SG));
for(i=0;i<=x;++i)
for(j=0;j<=y;++j){
memset(flag,0,sizeof(flag));
for(p=1;p<=i;++p)
for(q=1;q<=maxq&&p*q<=i;++q){
for(o=-1,k=1;k<=q;++k) o=(o==-1)?SG[i-p*k][j]:(o^SG[i-p*k][j]);
if(o!=-1) flag[o]=true;
}
for(p=1;p<=j;++p)
for(q=1;q<=maxq&&p*q<=j;++q){
for(o=-1,k=1;k<=q;++k) o=(o==-1)?SG[i][j-p*k]:(o^SG[i][j-p*k]);
if(o!=-1) flag[o]=true;
}
for(o=0;;++o)
if(!flag[o]){
SG[i][j]=o;
break;
}
}
}
int main(){
int i;
scanf("%d",&T);
while(T--){
int now=0,o;
scanf("%d%d",&n,&maxq);
solve2();
for(i=1;i<=n;++i){
scanf("%d",&o);
if(o) continue;
int o2=0,o3=0;
o=i;while(o%2==0) ++o2,o/=2;
while(o%3==0) ++o3,o/=3;
now^=SG[o2][o3];
}
if(now) printf("win\n");
else printf("lose\n");
}
return 0;
}