首先需要预处理出x个石子能够进行的操作数,存到链表e[x]里面该步骤为n

对每一堆石子求sg函数,对每一堆石子枚举考虑该步骤能否是sg的异或为0,可以则方案数加一

注意:在分解操作中两个约数相同要排除,该操作不会影响sg,但会是方案数重复计算

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int f[N];
vector<int> e[N];
void divide(int x)
{
    for(int i=1;i*i<=x;++i)
    {
        if(x%i==0) 
        {
            e[x].push_back(i);
            //e[i]重复放元素不会影响sg的值,但在对步骤的统计中会重复计算方案数
            if(i!=x/i)
            e[x].push_back(x/i);
        }
    }
}
int sg(int x)
{
    if(~f[x]) return f[x];
    set<int> S;
    for(auto p:e[x])
    {
        S.insert(sg(x-p));
    }
    for(int i=0;;++i) if(!S.count(i)) return f[x]=i; 
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    memset(f,-1,sizeof f);
    f[0]=0;
    int n; cin>>n;
    for(int i=1;i<=1e5;++i) divide(i);
    vector<int> a(n);
    int ans = 0;
    for(int i=0;i<n;++i) 
    {
        cin>>a[i];
        ans^=sg(a[i]);
    }
    //cout<<ans<<'\n';
    int tmp = 0;
    long long res = 0;
    for(int i=0;i<n;++i)
    {
        tmp = ans^sg(a[i]);
        for(auto p:e[a[i]])
        {
            if((tmp^sg(a[i]-p))==0) res++;
        }
    }
    cout<<res<<"\n";
    
}