[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;
}
posted @ 2018-06-27 16:57  shanxizeng  阅读(133)  评论(0编辑  收藏  举报
广告位招商,有意者请联系