题意:
统计 \(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?'\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?'\n':' ');
}
return 0;
}