题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6892
思路:
最初的思路是这样:把长度作素因子分解,这样分解次数之和(可拆分次数)就可以视作为一堆石子,什么时候取完就是全为1的情况也就是最后状态,但是这样直接转化为尼姆游戏会与题目中所说的有所区别,分解一次,假设除m(从一堆中拿走任意多个素因子(素因子乘积为m)后)在题目中会形成m个堆,那么我们思考,既然被分解后会形成m个堆,这想法还对吗?我们可以这样思考,如果从中拿走任意非2质数,那么肯定会形成奇数个石子数量相同的堆,那么其实最后尼姆异或的结果仍是1个堆的值,新多出来的m-1个堆异或后为0。如果从中拿走2的任意次数,那么作用就是让尼姆异或的结果为0,这与从中拿走一个2的作用是相同的,故2的贡献只有1,因此结论分解形成m个堆稍作改进后就不会影响我们向尼姆博弈作的转化。
代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 31625;

int prime[MAXN], cnt;
bool vis[MAXN];
void Prime()
{
    for(int i = 2; i <= MAXN; i++) {
        if(!vis[i]) {
            prime[++cnt] = i;
        }
        for(int j = 1; j <= cnt ; j++) {
            if(i * prime[j] > MAXN) break;
            vis[i * prime[j]] = 1;
            if(i % prime[j] == 0) break;    //当 i是prime[j]的倍数时,i = kprime[j],如果继续运算 j+1,i * prime[j+1] = prime[j] * k prime[j+1],这里prime[j]是最小的素因子,当i = k * prime[j+1]时会重复,所以才跳出循环。 
        }
    }
}

int a[15], b[15];
int main()
{
    Prime();
    int t;
    cin >> t;
    while(t--)
    {
        memset(b, 0, sizeof(b));
        int n;
        cin >> n;
        for(int i = 0; i < n; i++) cin>>a[i];
        int ans = 0;
        for(int i = 0; i < n; i++){
            if(a[i]%2 == 0){
                while(a[i]%2 == 0){
                    a[i] >>=1;
                }
                b[i]++;
            }

            for(int j = 1; j <= cnt && prime[j] <= a[i]; j++){
                if(a[i]%prime[j] == 0){
                    while(a[i] % prime[j] == 0){
                        b[i]++;
                        a[i]/=prime[j];
                    }
                }    
            }
            if(a[i] > 1){
                b[i]++;
            }
            ans ^= b[i];
        }
        if(ans){
            puts("W");
        }
        else{
            puts("L");
        }
    }
}