CF1842G Tenzing and Random Operations 题解

题意

给定一个长度为 n 的正整数序列 a,对该序列进行 m 次操作,定义每次操作如下:

[1,n] 中等概率选取一个 i,对于 j[i,n],执行操作 ajaj+v,其中 v 是给定的常数。

m 次操作后 i=1nai 的期望,对 109+7 取模。

0n50001m,v,ai109)。

题解

转化为求全部方案的和。

发现对于任意方案,最终求的式子都形如 (ai+v+v+),根据乘法分配律,可以发现每一个整式会有一项产生贡献,若这个整式产生贡献的为一个 v,那么这就代表着一定钦定了一个操作选取了 [1,i] 中的点,具体的说,其贡献有如下三类:

  1. 选取 ai 产生贡献;

  2. 选取一个已经钦定了的操作产生的 v

  3. 钦定一个新的操作并选取其产生的 v

故可以进行 DP,设 fi,j 表示在 [1,i] 中钦定了 j 个操作的贡献和,那么有如下转移:

  1. 在这个整式中选取了 ai,有 fi,jai×fi1,j

  2. 在这个整式中选取了一个已经钦定了的操作产生的 v,枚举产生选取的 v 的那个操作,有 fi,jjv×fi1,j

  3. 钦定一个新的操作并选取其产生的 v,首先考虑从所有未钦定的 mj+1 个操作中选取一个,接下来考虑将其钦定为 [1,i] 中的哪个点,有 fi,j(mj+1)iv×fi1,j1

那么整个过程中最多钦定 min{n,m} 个操作,对于未钦定的操作,由于其未产生贡献,故可以随便选取端点,通过枚举钦定的操作的数量,可以得到答案为

i=0min{n,m}fn,i×nminm

总复杂度 O(n×min{n,m}),可以通过本题。

Code

#include <bits/stdc++.h>

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

constexpr valueType MOD = 1e9 + 7;

void Inc(valueType &a, valueType b) {
    a = a + b;

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

valueType sum(valueType a, valueType b) {
    return a + b >= MOD ? a + b - MOD : a + b;
}

valueType mul(valueType a, valueType b) {
    return (long long) a * b % MOD;
}

void Mul(valueType &a, valueType b) {
    a = (long long) a * b % MOD;
}

valueType pow(valueType a, valueType b) {
    valueType result = 1;

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

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

    return result;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    valueType N, M, V;

    std::cin >> N >> M >> V;

    ValueVector A(N + 1);

    for(valueType i = 1; i <= N; ++i)
        std::cin >> A[i];

    valueType const K = std::min(N, M);

    ValueMatrix F(N + 1, ValueVector(K + 1, 0));

    F[0][0] = 1;

    for(valueType i = 1; i <= N; ++i) {
        for(valueType j = 0; j <= K; ++j) {
            Inc(F[i][j], mul(F[i - 1][j], A[i]));
            
            Inc(F[i][j], mul(F[i - 1][j], mul(j, V)));

            if (j > 0)
                Inc(F[i][j], mul(F[i - 1][j - 1], mul(mul(M - j + 1, i), V)));
        }
    }

    valueType ans = 0;

    for(valueType i = 0; i <= K; ++i)
        Inc(ans, mul(F[N][i], pow(N, M - i)));
    
    ans = mul(ans, pow(pow(N, M), MOD - 2));

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

    return 0;
}
posted @   User-Unauthorized  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示