CF1626F A Random Code Problem 题解

题意

给定长度为 n 的数组 a 和一个整数 k ,执行下面的代码:

long long ans = 0; //定义一个初始值为0的长整型变量
for(int i = 1; i <= k; i++) {
	int idx = rnd.next(0, n - 1); //生成一个介于0到n-1的随机数(含0和n-1)
  								 //每个数被选中的概率是相同的
	ans += a[idx];
	a[idx] -= (a[idx] % i);
}

求代码运行结束后 ans 的期望值 Enk 相乘的结果,即 E×nk

1n107,1k17)。

题解

考虑计算 ans 的期望值 E,最后使之与 nk 相乘。设 P=lcm(1k1),可以看出数组 a 中的元素 ai 最多会被减去 aimodP。因此若将 ai 拆分为两部分:ai=aiP×P+aimodP,前半部分的贡献是不变的,为

k×P×i=0n1aiPn

下面着重考虑后半部分的贡献,因为值域较小,故考虑将其作为 DP 的状态。设 fi,j 为在第 i 次操作后模 Pj 的期望元素个数。有转移

fi,j(jmodi)1n×fi1,jfi,j(11n)×fi1,j

计算完成 f 数组后即可快速计算前半部分的贡献,为

i=0k1jj×fi,jn

总复杂度 O(n+kP),可以通过本题。

Code

#include <bits/stdc++.h>

typedef long long valueType;
typedef std::vector<valueType> ValueVector;
typedef std::vector<ValueVector> ValueMatrix;

constexpr valueType MOD = 998244353;

template<typename T1, typename T2, typename T3 = valueType>
void Inc(T1 &a, T2 b, const T3 &mod = MOD) {
    a = a + b;

    if (a >= mod)
        a -= mod;
}

template<typename T1, typename T2, typename T3 = valueType>
T1 sub(T1 a, T2 b, const T3 &mod = MOD) {
    return a - b < 0 ? a - b + mod : a - b;
}

template<typename T1, typename T2, typename T3 = valueType>
T1 mul(T1 a, T2 b, const T3 &mod = MOD) {
    return (long long) a * b % mod;
}

template<typename T1, typename T2, typename T3 = valueType>
void Mul(T1 &a, T2 b, const T3 &mod = MOD) {
    a = (long long) a * b % mod;
}

template<typename T1, typename T2, typename T3 = valueType>
T1 pow(T1 a, T2 b, const T3 &mod = MOD) {
    T1 result = 1;

    while (b > 0) {
        if (b & 1)
            Mul(result, a, mod);

        Mul(a, a, mod);
        b = b >> 1;
    }

    return result;
}

valueType lcm(valueType a, valueType b) {
    return a / std::__gcd(a, b) * b;
}

int main() {
    valueType N, A0, X, Y, K, M;

    std::cin >> N >> A0 >> X >> Y >> K >> M;

    ValueVector source(N);

    source[0] = A0;

    for (valueType i = 1; i < N; ++i)
        source[i] = (source[i - 1] * X + Y) % M;

    valueType P = 1;

    for (valueType i = 2; i < K; ++i)
        P = lcm(P, i);

    ValueMatrix F(K, ValueVector(P, 0));

    for (auto const &iter: source)
        ++F[0][iter % P];

    valueType const InvN = pow(N, MOD - 2), reverseN = sub(1, InvN);

    for (valueType k = 1; k < K; ++k) {
        for (valueType i = 0; i < P; ++i) {
            Inc(F[k][i - i % k], mul(F[k - 1][i], InvN));
            Inc(F[k][i], mul(F[k - 1][i], reverseN));
        }
    }

    valueType ans = 0;

    for (valueType k = 0; k < K; ++k)
        for (valueType i = 0; i < P; ++i)
            Inc(ans, mul(F[k][i], i));

    for (auto const &iter: source)
        Inc(ans, mul(iter / P * P, K));

    Mul(ans, InvN);

    Mul(ans, pow(N, K));

    std::cout << ans << std::endl;

    return 0;
}
posted @   User-Unauthorized  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示