Codeforces1327E - Count The Blocks(找规律/思维)

Description

You wrote down all integers from 0 to 10n−1, padding them with leading zeroes so their lengths are exactly n. For example, if n=3 then you wrote out 000, 001, …, 998, 999.

A block in an integer x is a consecutive segment of equal digits that cannot be extended to the left or to the right.

For example, in the integer 00027734000 there are three blocks of length 1, one block of length 2 and two blocks of length 3.

For all integers i from 1 to n count the number of blocks of length i among the written down integers.

Since these integers may be too large, print them modulo 998244353.

Input

The only line contains one integer n (1≤n≤2⋅105).

Output

In the only line print n integers. The i-th integer is equal to the number of blocks of length i.

Since these integers may be too large, print them modulo 998244353.

题目大意

输入一个n,求0-(10n-1)之间长度为1到n的数字块数分别是多少(数字长度不够n用前导0填充)
比如000334就有1个长度为1的块4,1个长度为2的块33,1个长度为3的块000

思路

解法1

设n,长度块数分别为a1,a2,a3…an
首先数字长度是固定的,一共有10n×n个数字,也就意味着a1,a2…之间是有关系的。
可以发现
a1×n+a2×(n-1)×…×an=10n×n。
再打个表

n=1
10-0
n=2
200-(a1+a1)
n=3
3000-(a1+a1)-(a1+a2+a2)
n=4
40000-(a1+a1)-(a1+a2+a2)-(a1+a2+a3+a3)

然后维护一下前缀一遍循环就可以算出来了

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll ans[maxn],pre[maxn],num;
ll pow_(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1)ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans;
}
int main()
{
    int n;
    scanf("%d",&n);
    ans[1]=pre[1]=10,num=0;
    for(int i=2;i<=n;++i){
        num=(num+pre[i-1]+ans[i-1])%mod;
        ans[i]=((pow_(10,i)*i)%mod-num+mod)%mod;
        pre[i]=(pre[i-1]+ans[i])%mod;
    }
    for(int i=n;i>=1;--i){
        printf("%lld ",ans[i]);
    }
    return 0;
}

解法2
考虑块的位置
块在前面的时候比如###&@@@@
设###的长度为i 那@@@@的长度就为n-i+1
所有的情况数为10(#可以有10个选择)×9(&可以有9个选择)×10n-i+1(@@@@随意组合)
在后面的情况
同在前面的情况
在中间如###&000%@@@@
也就是9×9×10×10n-i-2×(n-i-1)(位置选择)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll ans[maxn],pre[maxn],num;
ll pow_(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1)ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans;
}
int main()
{
    int n;
    scanf("%d",&n);
    ans[n]=10;
    ll a,b,c;
    for(int i=1;i<n;++i){
        a=0,b=0,c=0;
        if(n-i-1>=0){
            a=pow_(10,n-i-1)*10*9;
            b=pow_(10,n-i-1)*10*9;
        }
        if(n-i-2>=0){
            c=pow_(10,n-i-2)*9*9*10*(n-i-1);
        }
        ans[i]=(a%mod+b%mod+c%mod)%mod;
    }
    for(int i=1;i<=n;++i){
        printf("%lld ",ans[i]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43984169/article/details/105682422