题解 P4706【取石子】

Link

题意

n 堆棋子,第 i 堆有 ai 个棋子,定义一次操作为选择第 i 堆棋子中任意个棋子转移到第 j 堆中。其中 ji 的质因数。

两人轮流操作,不能操作者输。若先手第一步随机操作一步,问先手获胜的概率。对 998244353 取模。

1n106,0ai109

思路

前置知识:阶梯 Nim 博弈

描述:有 n 堆棋子,第 i 堆有 ai 个棋子,定义一次操作为选择第 i 堆棋子中任意个棋子转移到第 i1 堆中。两人轮流操作,不能操作者输。求先手是否有必胜策略。

可以得到,此时的 SG 函数 f(x)=a1 xor a3 xor a5 xor  xor an[2|n],此处不多作介绍,可以参考这份讲解


x 的标准分解式为 i=1kpiqi,定义 sx=k,cx=i=1kqi。这个可以线性筛出来。

我们发现,如果以 ci 的奇偶性分层连边,则问题转化为在奇偶层之间移动棋子的阶梯 Nim 博弈。

首先我们知道先手第一步走的方式有 i=1nsiai 种。

然后来判断有多少种合法方法。

枚举奇层的所有 i,若操作后 f(x) 变为 0,则先手能胜利,则定义 need=f(x) xor ai,则 ai 变为 needf(x) 变为 0

然后对于 needai 的大小分类讨论。

  • need=ai,此时 f(x)=0,若对 ai 做出改动,则 f(x) 定不等于 0,故此类无贡献;
  • need<ai,考虑将 i 处的 aineed 颗棋子转移至偶层,则对答案作出 si 的贡献;
  • need>ai,考虑枚举 ip=j,将偶层 j 处的 needai 颗棋子转移至奇层 i 处,则对答案作出 j=ip[ajneedai] 的贡献。

最后除一下得出概率就行了!

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
namespace IO{//by cyffff

}
const int N=1e6+10,mod=998244353;
int n,a[N],rnd,sol;
bitset<N>p;
int pri[N],cnt,sum[N];
bool odd[N];
/*
sum->质因数个数
odd->指数和是否为奇 
*/
inline int qpow(int x,int y){
    int res=1;
    while(y){
        if(y&1) res=1ll*res*x%mod;
        x=1ll*x*x%mod;
        y>>=1; 
    }
    return res;
}
inline void sieve(int n){
    p[1]=1;
    for(int i=2;i<=n;i++){
        if(!p[i]){
            pri[++cnt]=i;
            sum[i]=odd[i]=1;
        }
        for(int j=1;j<=cnt&&i*pri[j]<=n;j++){
            p[i*pri[j]]=1;
            odd[i*pri[j]]=odd[i]^1;
            if(i%pri[j]==0) { sum[i*pri[j]]=sum[i]; break; }
            sum[i*pri[j]]=sum[i]+1;
        }
    }
}
int SG;
int main(){
    n=read();
    sieve(n);
    for(int i=1;i<=n;i++){
        a[i]=read();
        if(odd[i]) SG^=a[i];
        rnd=(rnd+1ll*a[i]*sum[i])%mod;
    }
    for(int i=1;i<=n;i++){
        if(odd[i]){
            int need=SG^a[i];
            if(need==a[i]) continue;
            if(need<a[i]) sol=(sol+sum[i])%mod;
            else{
                for(int j=1;j<=cnt&&pri[j]*i<=n;j++){
                    if(a[i*pri[j]]>=need-a[i]) sol++;
                }
                sol-=sol>=mod?mod:0;
            }
        }
    }
    write(1ll*sol*qpow(rnd,mod-2)%mod);
    flush();
}

再见 qwq~

posted @   ffffyc  阅读(7)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示