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