1 条题解

  • 1
    @ 2022-12-9 15:27:22

    我们不妨把每个球的贡献分开统计。

    由于是环状的,我们计算一下位置的变化量。

    p=1mp=\frac1m,则

    (1p+pz)k(1-p+pz)^k

    可以描述一个球在 kk 步后走的步数的概率。

    (其实就是二项分布)

    由于是环状的,我们不妨做循环卷积。

    统计上每个球,即为

    (tatzt)(1p+pz)k(\sum_ta_tz^t)(1-p+pz)^k

    直接暴力循环卷积即可,复杂度 O(n2logk)O(n^2\log k)

    (当然,也可以用 FFT 优化卷积,甚至使用 FFT 本质直接优化循环卷积,但是没有必要)

    以下是核心代码。

    using poly=std::vector<dbl>;
    uint n,m,k;scanf("%u%u%u",&n,&m,&k);
    auto mul=[&](poly a,poly b)->poly
    {
        poly ans(std::min<uint>(a.size()+b.size()-1u,n));
        for(uint i=0;i<a.size();i++)for(uint j=0;j<b.size();j++)
            ans[(i+j)%n]+=a[i]*b[j];
        return ans;
    };
    poly base={(m-1.)/m,1./m};
    poly ans={1};
    while(k){
        if(k&1)ans=mul(ans,base);
        if((k>>=1))base=mul(base,base);
    }
    base.resize(n);
    for(uint i=0;i<n;i++)
        scanf("%lf",&base[i]);
    ans=mul(ans,base);
    ans.resize(n);
    for(uint i=0;i<n;i++)
        printf("%.3lf\n",ans[i]);
    
    • 1

    信息

    ID
    2510
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    (无)
    递交数
    63
    已通过
    9
    上传者