魔法珠

题意

n n n堆魔法珠,每次可以选择一堆大于 1 1 1的任意一堆

设这堆魔法珠有 m m m个约数分别为 b 1 , b 2 , b 3 . . . b m b_1,b_2,b_3...b_m b1,b2,b3...bm

那么把这堆石子分解为这 m m m堆的任意 m − 1 m-1 m1堆石子,所以一次操作后会增加 m − 2 m-2 m2堆石子

最后,谁不能操作谁就输了

a i , n < = 1000 a_i,n<=1000 ai,n<=1000


定义 s g [ i ] sg[i] sg[i]为一堆石子有 i i i个时的 s g sg sg

那么 i i i能到达的状态一共有 m m m个,即去掉 m m m个约数中任意一个约数都是一种状态

记忆化搜索即可

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1009;
int sg[maxn],ok[maxn],n;
int solve(int x)
{
	if( sg[x]!=-1 )	return sg[x];
	int temp = 0;
	for(int i=1;i<x;i++)
		if( x%i==0 )	temp ^= solve(i);
	for(int i=1;i<x;i++)
		if( x%i==0 )	ok[temp^solve(i)] = 1;
	for(int i=0;i<=x;i++)
		if( ok[i]==0 )	{ sg[x] = i; break; }
	for(int i=0;i<=x;i++)	ok[i] = 0;
	return sg[x]; 
}
int main()
{
	memset( sg,-1,sizeof sg ); sg[1] = 0;
	while( cin >> n )
	{
		int ans = 0;
		for(int i=1;i<=n;i++)
		{
			int x; cin >> x;
			ans ^= solve( x );
		}
		if( ans )	cout << "freda\n";
		else	cout << "rainbow\n";
	}
}