[SDOI2016]硬币游戏
这道题不难吧,为什么大佬们没有题解呢,一定是dalao们觉得太简单了吧,弄得我好几天才做出来。。。
很显然,直接按题意模拟即可,求出sg函数,异或和就好了,不知道sg函数的可以自己百度一下。。。非常神奇的网站
不知道为什么,大佬们都是每次输入n之后再算的sg函数,并且每次算的时候都用的是2的多少次方乘3的多少次方,明明直接求更简单的,效率也并不低。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Maxn=31000;
const int Maxm=2100;
int sg[Maxn][31];
int s[Maxm];
int n,m,c,t,ans;
void getsg() {
for(int i=1;i<=30000;i++) {
int temp=i;
int san=0,er=0;
while(temp%2==0) temp/=2,er++;
while(temp%3==0) temp/=3,san++;
for(int q=1;q<=20;q++) {
for(int k=1;k<=q;k++) {
for(int p=1,tempp=2;p*k<=er;p++,tempp*=2) {
int ans=0;
for(int j=1,temp2=tempp;j<=k;j++,temp2*=tempp)
ans^=sg[i/temp2][q];
s[ans]=1;
}
for(int p=1,tempp=3;p*k<=san;p++,tempp*=3) {
int ans=0;
for(int j=1,temp3=tempp;j<=k;j++,temp3*=tempp)
ans^=sg[i/temp3][q];
s[ans]=1;
}
}
while(s[sg[i][q]]) sg[i][q]++;
for(int k=1;k<=q;k++) {
for(int p=1,tempp=2;p*k<=er;p++,tempp*=2) {
int ans=0;
for(int j=1,temp2=tempp;j<=k;j++,temp2*=tempp)
ans^=sg[i/temp2][q];
s[ans]=0;
}
for(int p=1,tempp=3;p*k<=san;p++,tempp*=3) {
int ans=0;
for(int j=1,temp3=tempp;j<=k;j++,temp3*=tempp)
ans^=sg[i/temp3][q];
s[ans]=0;
}
}
}
}
}
int main() {
// freopen("test.in","r",stdin);
getsg();
scanf("%d",&t);
while(t--) {
ans=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) {
scanf("%d",&c);
if(c==0) ans^=sg[i][m];
}
if(ans==0) puts("lose");
else puts("win");
}
// fclose(stdin);
return 0;
}