Educational Codeforces Round 84 (Rated for Div. 2) E. Count The Blocks(数学/递推)
You wrote down all integers from 00 to 10n−110n−1 , padding them with leading zeroes so their lengths are exactly nn . For example, if n=3n=3 then you wrote out 000, 001, ..., 998, 999.
A block in an integer xx is a consecutive segment of equal digits that cannot be extended to the left or to the right.
For example, in the integer 0002773400000027734000 there are three blocks of length 11 , one block of length 22 and two blocks of length 33 .
For all integers ii from 11 to nn count the number of blocks of length ii among the written down integers.
Since these integers may be too large, print them modulo 998244353998244353 .
The only line contains one integer nn (1≤n≤2⋅1051≤n≤2⋅105 ).
In the only line print nn integers. The ii -th integer is equal to the number of blocks of length ii .
Since these integers may be too large, print them modulo 998244353998244353 .
1
10
2
弄了挺长时间== 可以这么考虑,对于输入的n,0~10^n-1里面所有数的长度由于前导0的存在都变成了n,故长度为n的块只可能是0......0(n个),1......1(n个),......,9......9(n个),所以对于任何n,长度为n的块都是10个。同时,比方说n=4时的1234这个数,长为1的块的数目为4,可以
添上1使之变为11234
,也可以添上2使之变为12234......,因此n=k-1时长度为m的块的数量为n=k时长度为m+1的块的数量(可能不对?不知道怎严谨证明),所以n=k时只需要求长度为1的块的数量即可,其他都可以从n=k的情况转移过来,怎么求呢?先假设每个数每一位都不一样,则长度为1的块的数量为n*10^n,然后减去长度为2,3,4...n的块的数量*长度,就能得到a[1]了。
注意遇到减法取模时要加上MOD。
#include <bits/stdc++.h> #define MOD 998244353 using namespace std; long long a[200005],pre[200005]; long long n; long long fpow(long long a,long long b) { long long ans=1; for(;b;b>>=1) { if(b&1)ans=ans%MOD*a%MOD; a=a*a%MOD; } return ans; } int main() { cin>>n; a[n]=10;a[n-1]=180; pre[n]=10,pre[n-1]=190; long long sum=390; int i; for(i=n-2;i>=1;i--) { a[i]=((n-i+1)%MOD*fpow(10,n-i+1)%MOD-sum%MOD+MOD)%MOD;//加一个MOD 防止出现负数 pre[i]=(a[i]%MOD+pre[i+1]%MOD)%MOD; sum=(sum%MOD+a[i]*2%MOD+pre[i+1]%MOD)%MOD; } for(i=1;i<=n;i++)cout<<a[i]<<' '; return 0; }
代码可以参考这篇https://blog.csdn.net/LebronGod/article/details/105068607