ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Educational Codeforces Round 118 (Rated for Div. 2) D. MEX Sequences

2022-05-05 18:02:20  阅读:219  来源: 互联网

标签:方案 Educational Rated 数为 个数 int MEX Mod


\(DP\)真的太难了啊!!
首先考虑到\(f(i, s)\)表示,从前\(i\)个数中选,最后一个数为\(a_i\),且\(MEX(a_1,....,a_i) = \left\{ \begin{aligned} a_{i} - 1 (s = 0) \\ a_{i} + 1(s = 1)\end{aligned} \right.\),因为有\(a_i\)的存在,那么\(MEX\)只能取这两种值。
列出方程:

\[f(i, a[i] - 1) = \sum\limits_{j = 1}^{i - 1}f(j, a[j] - 1)[a_j == a_i] + \sum\limits_{j = 1}^{i - 1}f(j, a[j] + 1)(a_j == a_i - 2) \]

\[f(i, a[i] + 1) = \sum\limits_{j = 1}^{i - 1}f(j, a[j] - 1)[a_j == a_i + 2] + \sum\limits_{j = 1}^{i - 1}f(j, a_j + 1)(a_j == a_i) \]

但是这样需要\(O(n ^ 2)\)复杂度。

而发现给定的\(a_i\)值很小,因此可以直接把这个作为状态。

\(f(j, s)\)表示从前i个数中选,\(MEX(...a_k) = j\),且最后一个数为\(a_k\),\(a_k = \left\{ \begin{aligned} j - 1 (s = 0) \\ j + 1(s = 1)\end{aligned} \right.\)的方案数,那么当前x影响的只有\(f(x + 1, s)\)与\(f(x - 1, s)\)这两种方案,这样复杂度就降为了\(O(n * 2)\)

下面进行分类讨论:
1. 若\(MEX = x + 1\),最后一个数为\(x\)的方案。
1.1 前\(i - 1\)个数\(MEX = x + 1\),最后一个数为\(x\)的方案。
1.2 前\(i - 1\)个数\(MEX = x + 1\),最后一个数为\(x\),再添加一个\(x\)的方案。
1.3 前\(i - 1\)个数\(MEX = x\),最后一个数为\(x - 1\),再添加一个\(x\)的方案。
那么方程如下:

\[f(x + 1, 0) = 2 * f(x + 1, 0) + f(x, 0) \]

2. 若\(MEX = x + 1\),最后一个数为\(x + 2\)的方案。
2.1 前\(i - 1\)个数\(MEX = x + 1\),最后一个数为\(x + 2\)的方案。
2.2 前\(i - 1\)个数\(MEX = x + 1\),最后一个数为\(x + 2\),再添加一个\(x\)的方案。
那么方程如下:

\[f(x + 1, 1) = 2 * f(x + 1, 1) \]

3. 若\(MEX = x - 1\),最后一个数为\(x\)的方案。
3.1 前\(i - 1\)个数\(MEX = x - 1\),最后一个数为\(x\)的方案。
3.2 前\(i - 1\)个数\(MEX = x - 1\),最后一个数为\(x\),再添加一个\(x\)的方案。
3.3 前\(i - 1\)个数\(MEX = x - 1\),最后一个数为\(x - 2\),再添加一个\(x\)的方案。
那么方程如下:

\[f(x - 1, 1) = 2 * f(x - 1, 1) + f(x - 1, 0) \]

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
const int Mod = 998244353;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--) {
        //memset(f, 0, sizeof f);
        int n;
        cin >> n;
        vector<int> a(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        vector<vector<ll>> f(n + 2, vector<ll>(4, 0));
        f[0][0] = 1;
        //f[0][1] = ;
        for (int i = 0; i < n; i++) {
            int x = a[i];
            f[x + 1][0] = (f[x + 1][0] * 2 % Mod + f[x][0]) % Mod;
            f[x + 1][1] = f[x + 1][1] * 2 % Mod;
            
            if (x > 0) {
                f[x - 1][1] = (f[x - 1][1] * 2 % Mod + f[x - 1][0]) % Mod;
            }
        } 
        
        ll res = 0;
        for (int i = 0; i <= n; i++) {
            res = (res + f[i][0] + f[i][1]) % Mod;
        }

        cout << (res - 1 + Mod) % Mod << "\n";
    }

    return 0;
}

标签:方案,Educational,Rated,数为,个数,int,MEX,Mod
来源: https://www.cnblogs.com/ZhengLijie/p/16225725.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有