【Codeforces 1327E】Count The Blocks

题目链接

链接

翻译

让你统计(0) ~ (10^n-1) 中长度为 (len) 的连续块的个数

题解

考虑长度为 (len) 的连续块的位置,有两种情况

  • ①连续块紧接着开头或结尾,即xxxx........ 以及 .......xxxx 这两种
  • ②连续块在中间 ....xxxx.....

对于第①种情况,开头或结尾的连续块有 (10) 种可能,而和这个连续块紧接着的一个单元(注意是单元而不是块),有 (9) 种可能,因为不能和这个块相同。

然后剩余 (n-len-1) 个单元随意放, 有 (10^{n-len-1}) 种可能。

有头尾 (2) 种,所以第①种情况对应了 (2*10*9*10^{n-len-1})

第②种情况,和这个连续块(10种可能),左右相邻的两个单元只有 (9) 种可能,然后剩余 (n-len-2) 个位置随意放 (10^{n-len-2}),然后这个连续块在中间的话有

(n-len-1) 种放法(除了头尾),所以第二种情况就对应了 (10*9*9*10^{n-len-2}*(n-len-1)) 种方案。

注意 (len=n) 时特殊处理,答案为固定的 (10)

代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;

const LL MOD = 998244353;
const int N = 2e5;

int n;
LL _pow[N + 10];

int main(){
   // freopen("C://1.cppSourceProgram//rush.txt","r",stdin);
    ios::sync_with_stdio(0),cin.tie(0);
    //step5 算10^i
    _pow[0] = 1;
    for (int i = 1;i <= N; i++){
        _pow[i] = _pow[i-1]*10%MOD;
    }
    cin >> n;
    //step1 ite i
    for (int i = 1;i < n; i++){
        LL ans = 0;
        //step2 在头尾的情况
        ans = (ans + 10*9*2*_pow[n-i-1]%MOD)%MOD;
        //step3 在中间的情况
        ans = (ans + 10*9*9*_pow[n-i-2]%MOD*(n-i-1)%MOD)%MOD;
        cout << ans <<" ";
    }
    //step4 len=n
    cout << 10 << endl;
    return 0;
}

原文地址:https://www.cnblogs.com/AWCXV/p/14135322.html