【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;
}

posted @ 2020-12-14 19:56  AWCXV  阅读(93)  评论(0编辑  收藏  举报