Atcoder Beginner Contest 224 F 题解

题目链接

题目大意

给定一个长度为 N N N 的字符串 S S S S S S 仅由数字组成。

现在往 S S S 内部 插入 k k k + + + 0 ⩽ k < N 0 \leqslant k \lt N 0k<N),例如 S = 1234 S = 1234 S=1234,其中一种插入为 12 + 3 + 4 12+3+4 12+3+4

定义字符串 T T T 的值 f ( T ) f(T) f(T) 为:把 T T T 看作数学表达式后,对 T T T 做运算的结果;若 T T T 不合法,即两个及以上的 + + + 连续出现,那么规定 f ( T ) = 0 f(T) = 0 f(T)=0

例如上述 T = 12 + 3 + 4 T = 12+3+4 T=12+3+4,则 f ( T ) = 12 + 3 + 4 = 19 f(T) = 12 + 3 + 4 = 19 f(T)=12+3+4=19

∑ ∀ 插入方式 f ( S ′ ) \sum\limits_{\forall 插入方式}{f(S')} 插入方式f(S),其中 S ′ S' S 为插入 + + + 后的 S S S。答案对 998244353 998244353 998244353 取模。

数据范围

  • 1 ⩽ N ⩽ 2 × 1 0 5 1 \leqslant N \leqslant 2 \times 10^5 1N2×105
  • S S S 仅包含 1 ,   2 ,   3 ,   4 ,   5 ,   6 ,   7 ,   8 ,   9 1, \ 2, \ 3, \ 4, \ 5, \ 6, \ 7, \ 8, \ 9 1, 2, 3, 4, 5, 6, 7, 8, 9

Sample

输入

1234

输出

1736

样例解释:

所有合法的插入为 1234 ,   123 + 4 ,   12 + 34 ,   12 + 3 + 4 ,   1 + 234 ,   1 + 23 + 4 ,   1 + 2 + 34 ,   1 + 2 + 3 + 4 1234, \ 123+4, \ 12+34, \ 12+3+4, \ 1+234, \ 1+23+4, \ 1+2+34, \ 1+2+3+4 1234, 123+4, 12+34, 12+3+4, 1+234, 1+23+4, 1+2+34, 1+2+3+4,它们值的和为 1736 1736 1736

Solution

暴力枚举的复杂度是 2 N 2^N 2N,铁超时,所以我们肯定要考虑每个位置对答案的贡献。

在一个加法运算式中,我们可以分别考虑每个数位,例如对于表达式 123 + 45 + 6 123 + 45 + 6 123+45+6,百位加起来是 1 + 0 + 0 = 1 1 + 0 + 0 = 1 1+0+0=1,十位加起来是 2 + 4 + 0 = 6 2 + 4 + 0 = 6 2+4+0=6,个位加起来是 3 + 5 + 6 = 14 3 + 5 + 6 = 14 3+5+6=14,最后配上各自的权重 100 ,   10 ,   1 100, \ 10, \ 1 100, 10, 1,就能得到答案为 1 × 100 + 6 × 10 + 14 × 1 = 174 1 \times 100 + 6 \times 10 + 14 \times 1 = 174 1×100+6×10+14×1=174

这启发我们去考虑 S S S 的每个字符可能在 1 0 k ,   k = 0 ,   1 ,   2 , ⋯ 10^k, \ k = 0, \ 1, \ 2, \cdots 10k, k=0, 1, 2, 出现,以此进行贡献的计算。

考虑枚举到第 i ∈ [ 0 ,   N − 1 ) i \in [0, \ N - 1) i[0, N1) 个字符,且 S i S_i Si 右侧至少有一个 + + +,设这个 + + + 插在了 S j S_j Sj 之后。

考虑 S S S 一共有 N − 1 N - 1 N1 个位置可以插入 + + +,现在 [ i ,   j ] [i, \ j] [i, j] 后都无法插入 + + +,所以仅剩 ( N − 1 ) − ( j − i + 1 ) = N − ( j − i ) − 2 (N - 1) - (j - i + 1) = N - (j - i) - 2 (N1)(ji+1)=N(ji)2 个位置可以插入 + + +,那么 S i S_i Si 对答案的贡献就是

S i ∑ j = i N − 2 1 0 j − i ⋅ 2 N − ( j − i ) − 2 S_i \sum\limits_{j = i}^{N - 2}10^{j - i} \cdot 2^{N - (j - i) - 2} Sij=iN210ji2N(ji)2

j : = j − i j := j - i j:=ji 后得到

S i ∑ j = 0 N − i − 2 1 0 j ⋅ 2 N − j − 2 = 2 N − 2 ⋅ S i ∑ j = 0 N − i − 2 5 j = 2 N − 2 ⋅ S i ⋅ 5 N − i − 1 − 1 4 \begin{align*} &S_i \sum\limits_{j = 0}^{N - i - 2}10^j \cdot 2^{N - j - 2} \\ = &2^{N - 2} \cdot S_i \sum\limits_{j = 0}^{N - i - 2}5^j \\ = &2^{N - 2} \cdot S_i \cdot \frac{5^{N - i - 1} - 1}{4} \end{align*} ==Sij=0Ni210j2Nj22N2Sij=0Ni25j2N2Si45Ni11

i ∈ [ 0 ,   N − 1 ) i \in [0, \ N - 1) i[0, N1) 求和得到(这里为了防止 N = 1 N = 1 N=1 计算出错,让外面的 2 2 2 多乘一个)

2 N − 1 ∑ i = 0 N − 2 S i ⋅ 5 N − i − 1 − 1 8 2^{N - 1} \sum\limits_{i = 0}^{N - 2}S_i \cdot \frac{5^{N - i - 1} - 1}{8} 2N1i=0N2Si85Ni11

考虑枚举到第 i ∈ [ 0 ,   N ) i \in [0, \ N) i[0, N) 个字符,且 S i S_i Si 右侧没有一个 + + +

这种情况下只有 S j ,   j ∈ [ 0 ,   i ) S_j, \ j \in [0, \ i) Sj, j[0, i) 可以在其右侧插入 + + + 了,而 S i S_i Si 出现的位置是恒定的 1 0 N − i − 1 10^{N - i - 1} 10Ni1

因此这种情况的答案为 S i ⋅ 1 0 N − i − 1 ⋅ 2 i S_i \cdot 10^{N - i - 1} \cdot 2^i Si10Ni12i,求和即为

1 0 N − 1 ∑ i = 0 N − 1 S i 5 i 10^{N - 1} \sum\limits_{i = 0}^{N - 1} \frac{S_i}{5^i} 10N1i=0N15iSi

综上所述,总的答案即为

2 N − 1 ∑ i = 0 N − 2 S i ⋅ 5 N − i − 1 − 1 8 + 1 0 N − 1 ∑ i = 0 N − 1 S i 5 i 2^{N - 1} \sum\limits_{i = 0}^{N - 2}S_i \cdot \frac{5^{N - i - 1} - 1}{8} + 10^{N - 1} \sum\limits_{i = 0}^{N - 1} \frac{S_i}{5^i} 2N1i=0N2Si85Ni11+10N1i=0N15iSi

考虑到 i = N − 1 i = N - 1 i=N1 时, 5 N − i − 1 − 1 = 0 5^{N - i - 1} - 1 = 0 5Ni11=0,所以我们再化简几步

2 N − 1 ∑ i = 0 N − 2 S i ⋅ 5 N − i − 1 − 1 8 + 1 0 N − 1 ∑ i = 0 N − 1 S i 5 i = 2 N − 1 ∑ i = 0 N − 1 S i ⋅ 5 N − i − 1 − 1 8 + 2 N − 1 ∑ i = 0 N − 1 S i ⋅ 5 N − i − 1 = 2 N − 1 ∑ i = 0 N − 1 S i ⋅ 9 ⋅ 5 N − i − 1 − 1 8 \begin{align*} &2^{N - 1} \sum\limits_{i = 0}^{N - 2}S_i \cdot \frac{5^{N - i - 1} - 1}{8} + 10^{N - 1} \sum\limits_{i = 0}^{N - 1} \frac{S_i}{5^i} \\ = &2^{N - 1} \sum\limits_{i = 0}^{N - 1}S_i \cdot \frac{5^{N - i - 1} - 1}{8} + 2^{N - 1}\sum\limits_{i = 0}^{N - 1} S_i \cdot 5^{N - i - 1} \\ = &2^{N - 1} \sum\limits_{i = 0}^{N - 1}S_i \cdot \frac{9 \cdot 5^{N - i - 1} - 1}{8} \end{align*} ==2N1i=0N2Si85Ni11+10N1i=0N15iSi2N1i=0N1Si85Ni11+2N1i=0N1Si5Ni12N1i=0N1Si895Ni11

最终答案即为

2 N − 1 8 ∑ i = 0 N − 1 S i ⋅ ( 9 ⋅ 5 N − i − 1 − 1 ) \frac{2^{N - 1}}{8} \sum\limits_{i = 0}^{N - 1}S_i \cdot (9 \cdot 5^{N - i - 1} - 1) 82N1i=0N1Si(95Ni11)

C++ Code

#include <bits/stdc++.h>

using i64 = int64_t;
using u64 = uint64_t;
using f64 = double_t;
using i128 = __int128_t;

template<class T>
constexpr T power(T a, i64 b) {
    T res = 1;
    for (; b; b /= 2, a *= a) {
        if (b % 2) {
            res *= a;
        }
    }
    return res;
}
template<int P>
struct MInt {
    int x;
    constexpr MInt() : x{} {}
    constexpr MInt(i64 x) : x{norm(x % getMod())} {}
     
    static int Mod;
    constexpr static int getMod() {
        if (P > 0) {
            return P;
        } else {
            return Mod;
        }
    }
    constexpr static void setMod(int Mod_) {
        Mod = Mod_;
    }
    constexpr int norm(int x) const {
        if (x < 0) {
            x += getMod();
        }
        if (x >= getMod()) {
            x -= getMod();
        }
        return x;
    }
    constexpr int val() const {
        return x;
    }
    explicit constexpr operator int() const {
        return x;
    }
    constexpr MInt operator-() const {
        MInt res;
        res.x = norm(getMod() - x);
        return res;
    }
    constexpr MInt inv() const {
        assert(x != 0);
        return power(*this, getMod() - 2);
    }
    constexpr MInt &operator*=(MInt rhs) & {
        x = 1LL * x * rhs.x % getMod();
        return *this;
    }
    constexpr MInt &operator+=(MInt rhs) & {
        x = norm(x + rhs.x);
        return *this;
    }
    constexpr MInt &operator-=(MInt rhs) & {
        x = norm(x - rhs.x);
        return *this;
    }
    constexpr MInt &operator/=(MInt rhs) & {
        return *this *= rhs.inv();
    }
    friend constexpr MInt operator*(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res *= rhs;
        return res;
    }
    friend constexpr MInt operator+(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res += rhs;
        return res;
    }
    friend constexpr MInt operator-(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res -= rhs;
        return res;
    }
    friend constexpr MInt operator/(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res /= rhs;
        return res;
    }
    friend constexpr std::istream &operator>>(std::istream &is, MInt &a) {
        i64 v;
        is >> v;
        a = MInt(v);
        return is;
    }
    friend constexpr std::ostream &operator<<(std::ostream &os, const MInt &a) {
        return os << a.val();
    }
    friend constexpr bool operator==(MInt lhs, MInt rhs) {
        return lhs.val() == rhs.val();
    }
    friend constexpr bool operator!=(MInt lhs, MInt rhs) {
        return lhs.val() != rhs.val();
    }
};
 
template<>
int MInt<0>::Mod = 998244353;
 
template<int V, int P>
constexpr MInt<P> CInv = MInt<P>(V).inv();
 
constexpr int P = 998244353;
using Z = MInt<P>;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    std::cout << std::fixed << std::setprecision(12);
    
    std::string S;
    std::cin >> S;

    int N = S.size();
    
    Z ans = 0;
    for (int i = 0; i < N; i++) {
        ans += (S[i] - '0') * (9 * power(Z(5), N - i - 1) - 1);
    }
    ans *= power(Z(2), N - 1) / 8;

    std::cout << ans << "\n";
	  
    return 0;
}
AtCoder Beginner Contest 134 是一场 AtCoder 的入门级比赛,以下是每道题的简要题解: A - Dodecagon 题目描述:已知一个正十二边形的边长,求它的面积。 解题思路:正十二边形的内角为 $150^\circ$,因此可以将正十二边形拆分为 12 个等腰三角形,通过三角形面积公式计算面积即可。 B - Golden Apple 题目描述:有 $N$ 个苹果和 $D$ 个盘子,每个盘子最多可以装下 $2D+1$ 个苹果,求最少需要多少个盘子才能装下所有的苹果。 解题思路:每个盘子最多可以装下 $2D+1$ 个苹果,因此可以将苹果平均分配到每个盘子中,可以得到最少需要 $\lceil \frac{N}{2D+1} \rceil$ 个盘子。 C - Exception Handling 题目描述:给定一个长度为 $N$ 的整数序列 $a$,求除了第 $i$ 个数以外的最大值。 解题思路:可以使用两个变量 $m_1$ 和 $m_2$ 分别记录最大值和次大值。遍历整个序列,当当前数不是第 $i$ 个数时,更新最大值和次大值。因此,最后的结果应该是 $m_1$ 或 $m_2$ 中较小的一个。 D - Preparing Boxes 题目描述:有 $N$ 个盒子和 $M$ 个物品,第 $i$ 个盒子可以放入 $a_i$ 个物品,每个物品只能放在一个盒子中。现在需要将所有的物品放入盒子中,每次操作可以将一个盒子内的物品全部取出并分配到其他盒子中,求最少需要多少次操作才能完成任务。 解题思路:首先可以计算出所有盒子中物品的总数 $S$,然后判断是否存在一个盒子的物品数量大于 $\lceil \frac{S}{2} \rceil$,如果存在,则无法完成任务。否则,可以用贪心的思想,每次从物品数量最多的盒子中取出一个物品,放入物品数量最少的盒子中。因为每次操作都会使得物品数量最多的盒子的物品数量减少,而物品数量最少的盒子的物品数量不变或增加,因此这种贪心策略可以保证最少需要的操作次数最小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值