HDU6892 2020中国大学生程序设计竞赛(CCPC) - 网络选拔赛 1005. Lunch(博弈/SG函数)

Problem Description

Now it's time for lunch. Today's menu is chocolate!

Though every baby likes chocolate, the appetites of babies are little. After lunch, there are still n pieces of chocolate remained: The length of the ith piece is li.

Using the remained chocolate, Baby Volcano is going to play a game with his teacher, Mr. Sprague. The rule of the game is quite simple.

Two player plays in turns, and Baby Volcano will play first:

\1. In each turn, the player needs to select one piece of chocolate. If the length of the selected piece is equal to 1, the player of this turn will lose immediately.
\2. Suppose the length of the selected piece is l. Then the player needs to select a positive integer k satisfying k is at least 2 and k is a factor of l.
\3. Then the player needs to cut the selected piece into k pieces with length lk.

The game continues until one player selects a piece of chocolate with length 1.

Suppose both players plays optimally, your task is to determine whether Baby Volcano will win.

Input

The first line contains single integer t(1≤t≤2∗104), the number of testcases.

For each testcase, the first line contains a single integer n(1≤n≤10).

The second line contains n positive integers li(1≤li≤109), representing the length of each piece.

Output

For each testcase, output char 'W' if Baby Volcano will win, otherwise output char 'L'.

Sample Input

3
2
4 9
2
2 3
3
3 9 27

Sample Output

W
L
L

首先不难根据SG定理写出来打表代码,最后计算mex更新当前状态的SG)。观察发现每个状态x的SG值实际上就是x的奇质因子个数 + [x为偶数]​(并没有看出来

可以归纳地证明:

  1. SG(1) = 0, SG(p) = 1(p为质数)。

  2. 奇合数的SG为其质因子的次数和(当然没有2),

证明:考虑归纳,设状态为x=p1p2p3...pk,其中pxpy可能相等。当k = 1,SG(p1)显然成立。设k = n时SG(p1p2...pn)=n,则k = n + 1时,x=p1p2...pn+1可以分解出来p1p2...pn所有可以分解出来的子状态(他们的SG值覆盖了0到n - 1,同时由于x没有2这个因子,因此对mex的贡献不为0),除了这些子状态,x=p1p2...pn+1还能分解出p1p2...pn这个子状态,而这个子状态由归纳可知其SG值为n,又有p1p2...pn=(p1p2...pn+1)/pn+1,因为pn+1为奇数,所以这个子状态的值异或pn+1次得到的还是SG(p1p2...pn)=n,因此之前的那些SG值覆盖了0到n - 1,这个SG值为n,故SG(x=p1p2p3...pk)=n+1,得证。

  1. 偶合数的SG为其奇质因子的次数和 + 1。

证明:偶合数一定可以写成x=2kpm的形式,其中pm为奇质数。设这个状态的某个子状态为y,当x/y为偶数的时候显然偶数个SG(y)异或得到0,因此只考虑为奇数的情况(即2k存在于每个子状态)。同样采用归纳法:当状态为2k时SG为1,设状态为2kp1p2...pn1为n,则2kp1p2...pn可以分解出2kp1p2...pn1的所有子状态以及2kp1p2...pn1这个子状态,覆盖的范围是[0,n],因此mex为n + 1,得证。

因此最终的代码只需要先打1×109的素数表,对每个输入的数分解质因数计算SG函数值就可以转化为Nim游戏的模型,异或起来判断即可。注意打素数表范围不能太大否则会T,以及最好用线性筛。别忘了特判l本身是素数的情况!

#include <bits/stdc++.h>
using namespace std;
int n, sg[200005], vis[200005];
int p[100005], m = 0;
int v[100005];
void primes(int x) {
	memset(v, 0, sizeof(v));
	m = 0;
	for(int i = 2; i <= x; i++) {
		if(v[i] == 0) {
			v[i] = i;
			p[++m] = i;
		}
		for(int j = 1; j <= m; j++) {
			if(p[j] > v[i] || p[j] > x / i) break;
			if(i * p[j] <= 100000) v[i * p[j]] = p[j];
 		}
	}
}
void dabiao() {
	memset(sg, 0, sizeof(sg));
	sg[1] = 0;
	for(int i = 2; i <= 20000; i++) {
		memset(vis, 0, sizeof(vis));
		for(int k = 1; k * k <= i; k++) {
			if(i % k != 0) continue;
			int tmp = 0, tmp1 = 0;
			if(k * k == i) {
				if(k & 1) tmp ^= sg[k];
				vis[tmp] = 1;
			} else {
				int k1 = k, k2 = i / k;
				if(k1 & 1) tmp ^= sg[k2];
				vis[tmp] = 1;
				if(k2 & 1) tmp1 ^= sg[k1];
				vis[tmp1] = 1;
			}
		}
		for(int j = 0; ; j++) {
			if(!vis[j]) {
				sg[i] = j;
				break;
			}
		}
	}
}
int getSG(int x) {
	if(x == 1) return 0;
	int cnt = 0;
	int xx = x;
	for(int i = 1; i <= m; i++) {//m的范围是根号1e9内素数的个数,只需要判断这么多
		if(xx == 1) break;
		while(xx % p[i] == 0) {
			xx /= p[i];
			if((p[i] == 2 && !cnt) || p[i] != 2) cnt++;
		}
	}
	cnt += (xx != 1);//如果最后没有除尽 说明x是一个素数 因为打表范围不够1e9,因此只能这么判断
	return cnt;
}
int main() {
	int t;
	cin >> t;
	primes(50005);
	while(t--) {
		scanf("%d", &n);
		int tmp = 0;
		for(int i = 1; i <= n; i++) {
			int l;
			scanf("%d", &l);
			tmp ^= getSG(l);
		}
		if(tmp) printf("W\n");
		else printf("L\n");
	}
}
posted @   脂环  阅读(195)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2020-05-05 POJ3177 Redundant Paths(e-DCC+缩点)
2020-05-05 洛谷P3469 [POI2008]BLO-Blockade(割点)
点击右上角即可分享
微信分享提示
主题色彩