• AtCoder Beginner Contest 242(C~E)


    AB 水题

    C - 1111gal password

    题意:给出 N(\(2\le N\le 1e6\))求满足以下条件的 \(X\) 的数量,需除以模 (\(998244353\))

    • $X $ 是 \(N\) 位数
    • 对于 \(X_1,X_2,...,X_N\) 的每位数
      • \(1\le X_i \le 9\)
      • \(|X_i - X_{i+1}| \le 1\)

    思路:

    emm,直接看过去知道是比较明显的数论推导问题,随便写了几组发现当定义状态 \(f_{i,j}\) 表示长度为 \(i\) 符合条件的数字,结尾数位是 \(j\) 有多少个。递推式如下:

    \[\begin{array}{c} f_{i, j}=f_{i-1, j-1}+f_{i-1, j}+f_{i-1, j+1} \\ f_{i, 0}=f_{i, 10}=0 \\ f_{1, j}=1 \end{array} \]

    【AC Code】

    const int N = 1e6 + 10, mod = 998244353;
    ll n;
    ll f[N][11];
    int main() {
        ios::sync_with_stdio(false), cin.tie(nullptr);
        cout << fixed << setprecision(20);
        cin >> n;
        for (int i = 1; i <= 9; i += 1) f[1][i] = 1;
        for (int j = 2; j <= n; j++) 
            for (int i = 1; i <= 9; i++)
                f[j][i] = (f[j - 1][i - 1] + f[j - 1][i] + f[j - 1][i + 1]) % mod;
        // 定义初始和结尾以及初始值
        // {1,2,3,4,5}, accumulate(a[0], a[5],0ll) = 15
        cout << accumulate(f[n] + 1, f[n] + 10, 0ll) % mod;
    }
    

    D - ABC Transform

    题意:

    给定一个长度为 \(N\) 的字符串 \(S\) ,由A B C 三种字符组成,每一次变化会使 \(S\) 中的 A 全部变成 BCB 全部变成 CAC 全部变成 AB ,如 ABC 在一次变化后会变成 BCCAAB 。现在有 Q 个询问,每个询问都是求原串 \(S\) 经过 \(t_i\) 次变化后第 \(k_i\) 个字符

    分析:

    首先可以看出一个字符执行了 \(t\) 次操作以后的长度是好计算的,所以我们先把问题变成一个字符执行 \(t\) 次操作之后的第 \(k\) 个是什么。

    上面的东西可以考虑作为递归做,即定义函数类似 \(f(c,t,k)\) 表示字符 \(c\) 执行了 \(t\) 次操作得到的字符串第 \(k\) 个是什么,只是存在一个问题:\(t(\le 1e18)\) 太大了

    观察到每次操作会把字符串长度加倍,所以执行很少操作后,就变成了对 \(f(c,t,1)\) 求值。然而操作三次以后第一个字符等价于没有改变,所以可以直接得到结果。

    Update:发现原思路虽然正确但有点绕

    令 $f(t,k) $ 为原 \(S\) 经过 \(t_i\) 次变化后得到的 \(k_i\) 字符

    首先,当 \(t=0\) 时,直接输出 \(S_k\) 即可

    其次,当 \(t \not= 0\) ,我们需要知道 \(f(t,k)\) 从何而来

    样例

    ABC ->
    BCCAAB ->
    CAABABBCBCCA
    

    采用分类讨论的方法,不难发现

    • 当 $ k\in {2m+1 | m\in Z}$ (即 \(k\) 为奇数时),\(f(t - 1, \frac{k + 1}2) \to f(t,k)\)
    • 当 $ k\in {2m | m\in Z}$ (即 \(k\) 为偶数时),\(f(t - 1, \frac{k}2) \to f(t,k)\)

    怎么进行变化?

    可以概阔为一个 \(g\) 函数:

    inline char g(char ch, int x) { return (ch - 'A' + x) % 3 + 'A';}
    

    但是,如果我们每一次都去递归 \(t\) 还是太大了,直接炸了。那么只能动 \(k\)

    观察样例中字符串首,它们是 A B C 轮换的。

    利用这条性质,当 \(k=0\) 即可直接求 \(f(t,0) = g(S.front(),t mod 3)\)

    但是问题来了,这样一个算法肯定会对 \(k\) 取模,万一 \(k = 0...\)

    所以,我们把 \(S\) 的改为编号 \(0 \to N-1\)

    此时:

    • 当 $ k\in {2m+1 | m\in Z}$ (即 \(k\) 为奇数时),\(f(t - 1, \frac{k - 1}2) \to f(t,k)\)
    • 当 $ k\in {2m | m\in Z}$ (即 \(k\) 为偶数时),\(f(t - 1, \frac{k}2) \to f(t,k)\)

    代码就很好写了

    string s;
    ll q, t, k;
    inline char g(char ch, int x) { return (ch - 'A' + x) % 3 + 'A';}
    char f(ll t, ll k) {
        if (!t) return s[k];
        if (!k) return g(s[0], t % 3);
        return g(f(t - 1, k >> 1), (k & 1) + 1);
    }
    
    int main() {
        ios::sync_with_stdio(false), cin.tie(nullptr);
        cout << fixed << setprecision(20);
        cin >> s >> q;
        while (q --) {
            cin >> t >> k;
            cout << f(t, k - 1) << "\n";
        }
    }
    

    E - (∀x∀)

    title 好玩

    我们可以枚举两个字符串相同的前缀有多长,然后在后一个位置给串 \(X\) 填更小的字符,再之后的位置可以随便填了。

    • 需要判断 \(X\) 的前半段全部和 \(S\) 相同时,后半段是否小于等于 \(S\)
    const int N = 1e6, mod = 998244353;
    ll pw[N + 10] = {1};
    string s;
    int T, n;
    int main() {
        ios::sync_with_stdio(false), cin.tie(nullptr);
        cout << fixed << setprecision(20);
        for (int i = 1; i <= N; i += 1) pw[i] = pw[i - 1] * 26ll % mod;
        cin >> T;
        while (T--) {
            cin >> n >> s;
            s = "@" + s;
            int ans = 0;
            bool f = 1;
            for (int i = 1; i <= (n + 1) / 2; i++) {
                int a = s[i] - 'A', b = s[n + 1 - i] - 'A';
                ans = (ans + (ll)a * pw[(n + 1) / 2 - i]) % mod;
                f &= a <= b;
                f |= a < b;
            }
            cout << (ans + f) % mod << "\n";
        }
    }
    
  • 相关阅读:
    TensorFlow中使用GPU
    C++内存管理与注意事项
    深入理解Transformer及其源码
    Dropout原理与实现
    指针生成网络(Pointer-Generator-Network)原理与实战
    深度学习中的优化算法总结
    Hadoop伪分布式搭建
    集成学习总结
    模型评估
    基于Spring AOP实现的权限控制
  • 原文地址:https://www.cnblogs.com/RioTian/p/15976109.html
Copyright © 2020-2023  润新知