您的位置:首页 > 其它

2015年吉林省赛 Pin Pin Pin(矩阵快速幂)

2015-09-07 10:50 281 查看
题意:

我们把1~n的数连着写起来组成一个数,然后对1000000007取模f[1]=1,f[2]=12,..,f[9]=123456789...

n<=1e9,很明显我们可以得到一个递推式,f
= f[n-1]*k +n (k=10^(len(n))),由于n比较大我们需要用到矩阵来进行优化。

代码如下:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;

typedef long long LL;

const LL mod = 1e9+7;

const int maxn = 3;

struct matrix {
LL m[maxn][maxn];
matrix() {
memset(m,0,sizeof(m));
}
matrix operator*(const struct matrix &A)const {
matrix C;
for(int i=0; i<maxn; i++) {
for(int j=0; j<maxn; j++) {
for(int k=0; k<maxn; k++) {
C.m[i][j]=(C.m[i][j]+A.m[i][k]*m[k][j]%mod)%mod;
}
}
}
return C;
}
friend matrix operator ^ (matrix a,int k) {
matrix ans;
for(int i = 0; i<maxn; i++)
ans.m[i][i]=1;
while(k) {
if(k&1) ans = ans*a;
k>>=1;
a=a*a;
}
return ans;
}
};

LL a[11];

matrix I;

void init() {
a[0]=1;
for(int i=1; i<11; i++) {
a[i]=a[i-1]*(LL)10;
}
for(int i=0; i<maxn; i++) {
I.m[i][i]=1;
}
}

int main() {
init();
int t,n;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
matrix ans=I;
matrix A;
A.m[0][1]=1,A.m[0][2]=1;
A.m[1][1]=1,A.m[1][2]=1;
A.m[2][2]=1;
for(int i=0; i<11&&a[i]<=n; i++) {
int num;
A.m[0][0]=a[i+1];
if(a[i+1]<=n) num = a[i+1]-a[i];
else num = n-a[i]+1;
ans=ans*(A^num);
}
printf("%lld\n",ans.m[0][2]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: