牛客练习赛68 D.牛牛的粉丝 (期望DP,矩阵快速幂)

题目:传送门

题意

 思路

题解

#include <bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define UI unsigned int
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF 0x3f3f3f3f
#define inf LLONG_MAX
#define PI acos(-1)
#define fir first
#define sec second
#define lb(x) ((x) & (-(x)))
#define dbg(x) cout<<#x<<" = "<<x<<endl;
using namespace std;

const int N = 1e6 + 5;

const LL mod = 998244353;

LL n, a, b, c, x[N];

LL k;

LL ksm(LL a, LL b = mod - 2) {

    LL res = 1LL;

    while(b) {

        if(b & 1) res = res * a % mod;

        a = a * a % mod;

        b >>= 1;

    }

    return res;

}

LL p[N], tmp[N], res[N];

void mul(LL A[], LL B[], LL C[]) {

    rep(i, 0, n - 1) C[i] = 0LL;

    rep(i, 0, n - 1) {

        rep(j, 0, n - 1) {

            C[(i + j) % n] = (C[(i + j) % n] + A[i] * B[j] % mod) % mod;

        }

    }

}

LL ans[N];

void solve() {

    scanf("%lld %lld", &n, &k);

    scanf("%lld %lld %lld", &a, &b, &c);

    LL s = a + b + c; s = ksm(s);

    a = a * s % mod; b = b * s % mod; c = c * s % mod;

    rep(i, 0, n - 1) scanf("%lld", &x[i]);

    res[0] = 1LL; p[0] = c; p[1] = a; p[n - 1] = b;

    while(k) {

        if(k & 1) {

            mul(p, res, tmp);

            rep(i, 0, n - 1) res[i] = tmp[i];

        }

        mul(p, p, tmp);

        rep(i, 0, n - 1) p[i] = tmp[i];

        k >>= 1;

    }

    rep(i, 0, n - 1) rep(j, 0, n - 1) {

        ans[j] = (ans[j] + res[(j - i + n) % n] * x[i] % mod) % mod;

    }

    rep(i, 0, n - 1) printf("%lld ", ans[i]); puts("");

}


int main() {

//    int _; scanf("%d", &_);
//    while(_--) solve();

    solve();

    return 0;
}
原文地址:https://www.cnblogs.com/Willems/p/13585103.html