Lunch HDU - 6892 SG函数
题意
题目大意
给出n 个数,对于每个数 x 可以将每个数分成k个大小相等的数(k>2且k时x的因子),1 不可再分,问什么时候先手会胜。
思路
对于每个数,显然是1 必败,而 质数 必胜。
否则对于一个数n ,从2 到n,将n 按题意分解,
根据SG函数的性质,设
-
若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
本文作者:kingwzun
本文链接:https://www.cnblogs.com/kingwz/p/16696478.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步