1 条题解
-
0
自动搬运
来自洛谷,原作者为

ueettttuj
我爱学习搬运于
2025-08-24 21:34:03,当前版本为作者最后更新于2019-07-23 19:43:36,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
感觉其他大佬没多解释矩阵的构造,本蒟蒻来详细解释一下
首先此题是一道数位题,可以快速的推出方程
令 表示第位数为时的方案数
因为相邻两数之差不超过,故在第位时可以选取的数为~
故可以推出方程
方程展开为$f(i+1,j)=f(i,j-2)+f(i,j-1)+f(i,j)+f(i,j+1)+f(i,j+2)$
于是我们便可以推出答案
但是由于数据范围为 所以要用矩阵快速幂优化
根据递推式 我们可以推出矩阵
1 1 1 0 0 0 0 0 0 0 f[i,0] f[i,0]+f[i,1]+f[i,2] f[i+1,0] 1 1 1 1 0 0 0 0 0 0 f[i,1] f[i,0]+f[i,1]+f[i,2]+f[i,3] f[i+1,1] 1 1 1 1 1 0 0 0 0 0 f[i,2] f[i,0]+f[i,1]+f[i,2]+f[i,3]+f[i,4] f[i+1,2] 0 1 1 1 1 1 0 0 0 0 f[i,3] f[i,1]+f[i,2]+f[i,3]+f[i,4]+f[i,5] f[i+1,3] 0 0 1 1 1 1 1 0 0 0 x f[i,4] = f[i,2]+f[i,3]+f[i,4]+f[i,5]+f[i,6] = f[i+1,4] 0 0 0 1 1 1 1 1 0 0 f[i,5] f[i,3]+f[i,4]+f[i,5]+f[i,6]+f[i,7] f[i+1,5] 0 0 0 0 1 1 1 1 1 0 f[i,6] f[i,4]+f[i,5]+f[i,6]+f[i,7]+f[i,8] f[i+1,6] 0 0 0 0 0 1 1 1 1 1 f[i,7] f[i,5]+f[i,6]+f[i,7]+f[i,8]+f[i,9] f[i+1,7] 0 0 0 0 0 0 1 1 1 1 f[i,8] f[i,6]+f[i,7]+f[i,8]+f[i,9] f[i+1,8] 0 0 0 0 0 0 0 1 1 1 f[i,9] f[i,7]+f[i,8]+f[i,9] f[i+1,9]
令
1 1 1 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1为矩阵;
令
f[1,0] f[1,1] f[1,2] f[1,3] f[1,4] f[1,5] f[1,6] f[1,7] f[1,8] f[1,9]为矩阵;
所以我们只用将矩阵乘 遍 , 再将 就可以得出在第位取 ~ 的方案数,再将其累加即可得到答案
注意点:
-
中 因为要防止出现前导
-
当 时 , 需特判输出
下面放代码
#include <bits/stdc++.h> using namespace std; #define mod 1000000007 long long k; struct node{ long long m[11][11]; }; node res,ans,realans; node mul(node aa,node bb){ node tmp; memset(tmp.m,0,sizeof(tmp.m)); for(long long i=0;i<=9;i++){ for(long long j=0;j<=9;j++){ for(long long k=0;k<=9;k++){ tmp.m[i][j]=(tmp.m[i][j]+aa.m[i][k]*bb.m[k][j])%mod; } } } return tmp; } int main(){ scanf("%lld",&k); if(k==1){ printf("10\n"); return 0; } for(long long i=0;i<=9;i++){ ans.m[i][i]=1; } for(long long i=0;i<=9;i++){ for(long long j=max(0ll,i-2);j<=min(i+2,9ll);j++){ res.m[i][j]=1; } } k--; while(k){ if(k%2) ans=mul(ans,res); res=mul(res,res); k/=2; } long long anss=0; for(long long i=1;i<=9;i++) realans.m[i][0]=1; for(long long i=0;i<=9;i++){ for(long long j=0;j<=0;j++){ for(long long k=0;k<=9;k++){ anss=(anss+ans.m[i][k]*realans.m[k][j])%mod; } } } printf("%lld\n",anss); return 0; }神犇轻喷 -
- 1
信息
- ID
- 1089
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者