Lunch HDU - 6892 SG函数
题意
题目大意
给出n 个数,对于每个数 x 可以将每个数分成k个大小相等的数\(\frac{x}{k}\)(k>2且k时x的因子),1 不可再分,问什么时候先手会胜。
思路
对于每个数,显然是1 必败,而 质数 必胜。
否则对于一个数n ,从2 到n,将n 按题意分解,
根据SG函数的性质,设\(n = p ∗ q\)
-
若p 为偶数,那么可以得出其能到达的子局面的SG值为0(偶数个相同的数异或起来为0);
-
若p 为奇数,那么最终的SG值取决于SG(q)
但是 n 很大,无法暴力解决。我们对前一百个数打表求SG值。
通过打表,观察找规律可知:
- 若一个数的质因数分解式含有2 ,无论有多少2 ,对SG值的贡献只能是1 ,
- 奇质数对SG值的贡献是该质数的个数。
因此对于长度为l的巧克力,sg(l)等于l的非2质因数的指数和+l是否为偶数
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//typedef __int128 lll;
#define print(i) cout << "debug: " << i << endl
#define close() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define mem(a, b) memset(a, b, sizeof(a))
const ll mod = 1e9 + 7;
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
int p[maxn], cnt;
int flag[maxn];
void prime()
{
for(int i = 2; i < maxn; i++)
{
if(!flag[i]) p[cnt++] = i;
for(int j = 0; p[j] < maxn / i; j++)
{
flag[p[j] * i] = 1;
if(i % p[j] == 0) break;
}
}
}
int sg(int x)
{
int res = 0;
for(int i = 0; i < cnt && p[i] <= x / p[i]; i++)
{
if(x % p[i] == 0)
{
if(p[i] == 2)
{
res++;
while(x % p[i] == 0)
x /= p[i];
}
else
{
while(x % p[i] == 0)
x /= p[i], res++;
}
}
}
if(x > 1) res++;
return res;
}
int main()
{
prime();
int t; scanf("%d", &t);
while(t--)
{
int n; scanf("%d", &n);
int res = 0;
for(int i = 1; i <= n; i++)
{
int x; scanf("%d", &x);
res ^= sg(x);
}
printf("%s\n", res ? "W" : "L");
}
}
————————————————
版权声明:本文为CSDN博主「Happig丶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44691917/article/details/113384223