CodeFoeces 1327E

题意:

统计 (0,1,2,⋯,10^{n−1}) 所有数字中不同长度的连续区间数。
例如 (0111223) 中有 (2) 段长度为 (1) 的区间, (1) 段长度为 (2) 的区间, (1) 段长度为 (3) 的区间。(如果数字不足 (n) 位需要补充前导零)
数据范围:(1 leq n leq 2*10^5)

解法 (1)

打表,找规律:
(num[n]=10;)
(num[n-1]=180;)
(num[n-2]=2610;)
(num[i]=20*num[i+1]-100*num[i+2];(0<i<n-2))

代码:

#include <bits/stdc++.h>
using namespace std;
const int mod=998244353;
typedef long long ll;
const int N=2e5+5;
ll num[N];
int main()
{
    int n;
    scanf("%d",&n);
    num[n]=10;
    if(n>1)
        num[n-1]=180;
    if(n>2)
        num[n-2]=2610;
    for(int i=n-3;i>=1;i--)
        num[i]=((20*num[i+1]%mod)-(100*num[i+2]%mod)+mod)%mod;
    for(int i=1;i<=n;i++)
        printf("%lld%c",num[i],i==n?'
':' ');
    return 0;
}

解法 (2)

1.当 (i=n) 时,(num[i]=10)
2.当 (i<n) 时,考虑所求长度为 (i) 的序列在两端的情况。
(ans=2*10*9*10^{n-i-1})
3.当 (i<n-1) 时,考虑所求长度为 (i) 的序列在中间的情况。
(ans=(n-1-i)*10*9^2*10^{n-i-2})
用快速幂就可以求解。
代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
ll power(ll a,int b)
{
    ll res=1;
    while(b)
    {
        if(b&1)
            res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res%mod;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        ll res=0;
        if(i==n)
            res=10;
        if(i<n)
            res+=(2LL*10*9*power(10*1LL,n-i-1)%mod);
        if(i<n-1)
            res+=(1LL*(n-i-1)*10*9*9*power(10*1LL,n-i-2)%mod);
        printf("%lld%c",(res+mod)%mod,i==n?'
':' ');
    }
    return 0;
}

参考博客

原文地址:https://www.cnblogs.com/1024-xzx/p/12567509.html