对于博弈中的尼姆定理,是一个很由意思的博弈,当然操作范围也很大
由n堆若干个的石子,两个人轮流从某一堆取任意多的物品,规定每次至少取一个,多者不限,最后取光者得胜。
这里面有一个很核心的思路就是一种对称的操作,假设有两堆的情况下,一堆为a个石子,令一个也是a个石子,甲先对任何一个取了m个石子,只要乙乖巧的做一只复读机也取m个,那么甲必败。
那么当有n堆的情况呢
我也不知道(被打)(;´д`)ゞ
首先一步步地来,还是两堆,但是现在第一堆石子个数为a,第二堆的石子个数为b,且有a≠b
那么甲先手,只要取大的那c个,让它等于小的那一堆的数量即可,最后一定甲胜
然后考虑3个且随意取值的的情况,a,b,c
了解一下一下异或,a^b ^c=0则是先手必败。
不过我现在并不太会= =,以后会补一下看看,现在先看看另外一个东西,关于石子的抽象化处理,我们可以对石子进行一些限制,而这些限制下的取值又会发生什么了,最为普遍的公式就是SG函数的异或,这个也可以解决大部分模板问题了
2020 CCPC 1005 lunch
抽象出题目的意思,给你n堆石头,每一堆的石头有a[i],你可以把它分成a[i]/k份,当每一堆都是1时就输了;
对于一个奇数的一堆,根据唯一分解定理:任一大于1的自然数,要么本身是质数,要么可以分解为几个质数之积,且这种分解是唯一的。我们可以把这个数分成几个最小质因素相乘,而这些质因子就是石头的块数。
而对于偶数的一堆,首先知道对于两个相等的一堆,他们就是0,没有意义,8和4是等价的,也就是说对于2,2的任何次方都价于1,因此对于偶数的石头数就是取其奇质因数+1
好了完事
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include<cmath>
using namespace std;
#define RG register int
#define ll long long
const int maxn=3e4+2000;
int prime[maxn+5];
int visit[maxn+5];
void Prime(){
memset(visit,0,sizeof(visit));
memset(prime, 0,sizeof(prime));
for (int i = 2;i <= maxn; i++) {
// cout<<" i = "<<i<<endl;
if (!visit[i]) {
prime[++prime[0]] = i; //纪录素数, 这个prime[0] 相当于 cnt,用来计数
}
for (int j = 1; j <=prime[0] && i*prime[j] <= maxn; j++) {
//cout<<" j = "<<j<<" prime["<<j<<"]"<<" = "<<prime[j]<<" i*prime[j] = "<<i*prime[j]<<endl;
visit[i*prime[j]] = 1;
if (i % prime[j] == 0) {
break;
}
}
}
}
template <typename T>
inline void read(T &x){
x=0;
char c=0;
T w=0;
while(!isdigit(c))w|=c=='-',c=getchar();
while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
if(w) x=-x;
}
int main(){
Prime();
int T,n,f[15],ans;
int a[15];
read(T);
while(T--){
memset(f,0,sizeof(f));
read(n);
for(int i=1;i<=n;i++)
read(a[i]);
for(int i=1;i<=n;i++)
if(a[i]%2==0){
while(!(a[i]%2)){
a[i]/=2;
}
f[i]++;
}
for(int k=1;k<=n;k++){
for(int i=2;prime[i]<=a[k];i++){//寻找奇质因数的个数
if(prime[i]==0){
f[k]++;
break;}
while(!(a[k]%prime[i])) //
{
f[k]++;
a[k]/=prime[i];
}
}
}
ans=f[1];
for(int i=2;i<=n;i++)
ans^=f[i];
if(ans)printf("W\n");
else printf("L\n");
}
return 0;
}
注意事项:PS老白痴了,中间RE了N次,在求质因数的时候忘记考虑了大于32000的大素数,RE了5次。。。
PS麻木了,TLE,不过好歹知道int可以存1e10,建议全部int
AC了