链接:http://acm.whu.edu.cn/weblearn/problem/470
线性递推首先考虑 矩阵快速幂
long long 的范围为 9*10^18。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 3
typedef long long LL;
LL n,m=11;
struct Matrix
{
LL mat[N][N];
Matrix()
{
memset(mat,0,sizeof(mat));
}
};
Matrix mul(Matrix a,Matrix b)
{
Matrix res;
for(int i=0; i<N; i++)
for(int j=0; j<N; j++)
{
for(int k=0; k<N; k++)
{
res.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
res.mat[i][j]%=m;
}
}
return res;
}
Matrix pow_matrix(LL n,LL t)
{
Matrix res;
for(int i=0; i<N; i++)
res.mat[i][i]=1;
Matrix b; //每次矩阵快速幂前对矩阵进行改变,根据数据范围最多快速幂18次;
b.mat[0][0]=n%m;
b.mat[0][1]=b.mat[0][2]=b.mat[1][1]=b.mat[1][2]=b.mat[2][2]=1;
LL y=t+1-n/10;
while(y)
{
if(y&1)
res=mul(res,b);
y>>=1;
b=mul(b,b);
}
return res;
} //模板上的输入变量是:矩阵、数据长度;灵活运用模板,依题目而变(说着轻松)
int main()
{
while(~scanf("%lld",&n))
{
Matrix ans;
ans.mat[2][0]=1;
int x[9]= {0,1,1,2,2,3,3,3,4};
if(n<9)
{
printf("%d\n",x[n]);
continue;
}
LL t=10;
for(int i=1; i<=18; i++)
{
ans=mul(pow_matrix(t,t-1),ans);
t*=10;
if(t>n) break;
}
ans=mul(pow_matrix(t,n),ans);
printf("%lld\n",ans.mat[0][0]);
}
return 0;
}