首页 > 其他分享 >P10528 [XJTUPC2024] 崩坏:星穹铁道 题解

P10528 [XJTUPC2024] 崩坏:星穹铁道 题解

时间:2024-08-23 13:47:51浏览次数:10  
标签:matrix 星穹 题解 tr ret XJTUPC2024 mod dp size

求方案数,分多种情况,不难想到 DP。

设 \(dp_{i, j}\) 表示已经行动 \(i\) 次,剩余战技点个数为 \(j\) 的方案数,容易得到以下转移方程。

\(a_i = 1\) 时,有

\[dp_{i, j} = \begin{cases} 0, &j = 0, \\ dp_{i - 1, j - 1}, &1 \leqslant j \leqslant 4, \\ dp_{i - 1, j - 1} + dp_{i - 1, j}, &j = 5. \\ \end{cases} \]

\(a_i = 2\) 时,有

\[dp_{i, j} = \begin{cases} dp_{i - 1, j + 1}, &j = 0 \lor 2 \leqslant j \leqslant 4, \\ dp_{i - 1, j - 1} + dp_{i - 1, j + 1}, &j = 1, \\ 0, &j = 5. \\ \end{cases} \]

\(a_i = 3\) 时,有

\[dp_{i, j} = \begin{cases} dp_{i - 1, j + 1}, &j = 0, \\ dp_{i - 1, j - 1} + dp_{i - 1, j + 1}, &1 \leqslant j \leqslant 4, \\ dp_{i - 1, j - 1} + dp_{i - 1, j}, &j = 5. \\ \end{cases} \]

初始条件

\[dp_{0, k} = 1 \]

答案

\[\sum\limits_{i = 0}^5 dp_{n, i} \]

发现本题 \(n\) 可以达到 \(10^{18}\),并且转移方程形式固定,显然要使用矩阵乘法优化转移,将上面的三个转移分别写成矩阵 \(T_1, T_2, T_3\)。将角色行动一个循环视为一个单元,一个单元内的转移 \(T\) 可以用 \(T_1, T_2, T_3\) 表示,矩阵乘法优化完整的单元之间的转移,最后将剩余的行动次数补足即可。即总体的转移形如

\[T^{\lfloor \frac n 4 \rfloor} \prod\limits_{i = 1}^{n \mod 4} T_{a_i} \]

时间复杂度 \(O(k \log n)\),\(k\) 是矩阵乘法的常数。

#include <array>
#include <iostream>

typedef long long ll;

using namespace std;

const int mod = 998244353;

typedef array<ll, 6> vec;
typedef array<vec, 6> matrix;

inline ll operator*(const vec &v1, const vec &v2) {
    ll ret = 0;
    for (size_t i = 0; i < v1.size(); ++i)
        ret = (ret + v1[i] * v2[i] % mod) % mod;
    return ret;
}
inline vec operator*(const vec &v, const matrix &mat) {
    vec ret{};
    for (size_t i = 0; i < v.size(); ++i)
        for (size_t j = 0; j < mat.size(); ++j)
            ret[i] = (ret[i] + v[j] * mat[j][i] % mod) % mod;
    return ret;
}
inline matrix operator*(const matrix &m1, const matrix &m2) {
    matrix ret{};
    for (size_t i = 0; i < m1.size(); ++i)
        for (size_t j = 0; j < m2[0].size(); ++j)
            for (size_t k = 0; k < m2.size(); ++k)
                ret[i][j] = (ret[i][j] + m1[i][k] * m2[k][j] % mod) % mod;
    return ret;
}
inline matrix operator^(matrix mat, ll k) {
    matrix ret{};
    for (size_t i = 0; i < ret.size(); ++i)
        ret[i][i] = 1;
    while (k) {
        if (k & 1)
            ret = ret * mat;
        mat = mat * mat;
        k >>= 1;
    }
    return ret;
}

ll n, k;
int a[5];
matrix tr[4], trans;

static inline void solve() {
    tr[1][0][1] = tr[1][1][2] = tr[1][2][3] = tr[1][3][4] = tr[1][4][5] = tr[1][5][5] = 1;
    tr[2][5][4] = tr[2][4][3] = tr[2][3][2] = tr[2][2][1] = tr[2][1][0] = tr[2][0][1] = 1;
    tr[3][0][1] = tr[3][1][2] = tr[3][2][3] = tr[3][3][4] = tr[3][4][5] = tr[3][5][5] =
        tr[3][5][4] = tr[3][4][3] = tr[3][3][2] = tr[3][2][1] = tr[3][1][0] = 1;
    for (size_t i = 0; i < trans.size(); ++i)
        trans[i][i] = 1;
    cin >> n >> k;
    for (int i = 1; i <= 4; ++i) {
        cin >> a[i];
        trans = trans * tr[a[i]];
    }
    vec ans{};
    ans[k] = 1; // 初始化
    ans = ans * (trans ^ (n / 4)); // 整块的转移
    for (int i = 1; i <= n % 4; ++i) // 散块的转移
        ans = ans * tr[a[i]];
    int sum = 0;
    for (auto x : ans) // 统计答案
        sum = (sum + x) % mod;
    cout << sum << endl;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();
    return 0;
}

崩铁,启动!

标签:matrix,星穹,题解,tr,ret,XJTUPC2024,mod,dp,size
From: https://www.cnblogs.com/bluewindde/p/18375839

相关文章

  • LGP10702 [SNCPC2024] 下棋题解
    P10702[SNCPC2024]下棋本蒟蒻的第一篇题解定位博弈论(nim)+进制转换相关知识OIWIKI博弈论NIM进制转换正题读题所有k进制下所有数位的乘积为自身因子的数。他称之为LNC数。给出x枚棋子,然后LNC选定一个整数k(k≥2)。随后他们交替取走若干枚棋子,要求取走的棋......
  • 【题解】Solution Set - NOIP2024集训Day14 CDQ分治
    【题解】SolutionSet-NOIP2024集训Day14CDQ分治https://www.becoder.com.cn/contest/5482「CF364E」EmptyRectangles*3000摆烂了。「SDOI2011」拦截导弹CDQ的例题,之前做过(现在试图自己再做出来。第二问只用在第一问里面记录每一次是从哪个\(j\)​转移过来的,以及......
  • P10559 [ICPC2024 Xi'an I] The Last Cumulonimbus Cloud 题解
    这种题有一个常见的根号分治做法:设\(d\)为度数,显然有\(O(1)\)修改单点,\(O(d)\)查询邻域和\(O(d)\)修改邻域,\(O(1)\)查询单点两种暴力。对度数大于\(\sqrtn\)的点使用前者,度数小于等于\(\sqrtn\)的点使用后者,可以做到\(O(m\sqrtn)\)的时间复杂度。这种做法的本......
  • CF1575G GCD Festival 题解
    考虑欧拉反演\[\sum\limits_{d\midn}\varphi(d)=n\]则原式可以化为\[\begin{align*}&\sum\limits_{i=1}^n\sum\limits_{j=1}^n\gcd(a_i,a_j)\cdot\gcd(i,j)\\=&\sum\limits_{i=1}^n\sum\limits_{j=1}^n\gcd(a_i,a_j)\sum\li......
  • CF163E e-Government 题解
    题目传送门前置知识AC自动机|树状数组解法一次性将所有模式串加入AC自动机,然后处理加入和删除,考虑单次操作对答案的贡献。因为模式串\(T\)在文本串\(S\)中出现的次数之和等价于\(T\)在\(S\)的所有前缀中作为后缀出现的次数之和。这就很和\(fail\)树上跳到根节......
  • [题解] permutation
    [题解]Permutation解析一眼DP或者组合。70pts场上推的DP对于\((4,2,2)\),先把所有序列枚举出来:\[\begin{split}1\\\2\\1\\\3\\1\\\4\\--\\2\\\3\\2\\\4\\3\\\4\end{split}\]可以发现,对于分割线上的部分,可以看作\((3,1,1)\)的所有序列......
  • csp模拟27-金箱子(题解)
    题目链接(显然还没有找到原题)虽说我现在才学会期望dp显得不太好,但没办法,谁让我比较菜~~,之前模拟赛已经考过几道类似的题了,但都一笔带过了,这次算是正式学习了一下这类题,于是就有了这篇题解。首先看到k次方首先想到的就是我们在进行dp转移的时候不太方便,这个时候很自然的想到二项......
  • 题解:P9041 [PA2021] Fiolki 2
    \(\text{Link}\)题意给定一个\(n\)个点\(m\)条边的DAG,定义\(f(l,r)\)表示最多选取多少条不相交路径\((s_i,t_i)\)满足\(s_i\in[1,k],t_i\in[l,r]\),其中不能有任意一点同时在两条选出的路径上。对\(\forallx\in[0,k)\)求出有多少\([l,r]\sube(k,n]\)使得\(f(l,r)......
  • 题解:P10881「KDOI-07」能量场
    \(\text{Link}\)题意给你一个长为\(n\)的序列\(a_{1\dotsn}\),定义一条边\((u,v)\)的权值为\(a_u+a_v\)。对于一张图,定义其权值为包含的所有边的权值乘积。求所有\(n\)个点的有标号基环树的权值之和。对\(998244353\)取模。\(n\le10^3\)。思路非常厉害的题,zky倾......
  • 题解:P10698 [SNCPC2024] 最大流
    \(\text{Link}\)题意给定一个\(n\)个点\(m\)条边的单位网络,保证该网络不存在环。给定一个常数\(k\),设从\(1\)到\(i\)的最大流为\(f_i\),对\(\foralli\in[2,n]\)求出\(\min(f_i,k)\)。\(n\le10^5\),\(m\le2\times10^5\),\(k\le\min(n-1,50)\)。思路不相交路径,考......