數綿羊(矩陣快速冪)
阿新 • • 發佈:2018-12-17
問題描述
一個數:1234567891011121314151617181920…,數到了N,那麼形成的這個數字除以1000000007的餘數是多少呢? 輸入描述 一行,一個整數N,如題目描述 輸出描述 一行,一個整數,表示這個數字除以1000000007的餘數。 輸入樣例 10 輸出樣例 345678826 解釋: 12345678910%1000000007=345678826
30%的資料滿足:N<=20, 70%的資料滿足:N<=10000, 100%的資料滿足:N<=10^18
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const long long mod=1e9+7;
long long n;
struct node
{
long long m[3][3];
};
node mul(node a,node b)
{
node c;
memset(c.m,0,sizeof(c.m));
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
c.m[i][j]=(c.m[i][j]+(a.m[i][k]*b.m[k][j])%mod)%mod;
return c;
}
node quick_mod(node a,long long mi)
{
node ans;
memset(ans.m,0,sizeof(ans.m));
ans.m[0][0]=ans.m[1][1]=ans.m[2][2]=1;
while(mi)
{
if(mi&1) ans=mul(ans,a);
a=mul(a,a);
mi>>=1;
}
return ans;
}
int main()
{
cin>>n;
node ans;
memset(ans.m,0,sizeof(ans.m));
ans.m[0][1 ]=ans.m[0][2]=1ll;
long long now=1ll;
while(now<=n)
{
now*=10ll;
node a;
memset(a.m,0,sizeof(a.m));
a.m[0][0]=now%mod; a.m[1][0]=a.m[1][1]=a.m[2][1]=a.m[2][2]=1ll;
if(now>n) ans=mul(ans,quick_mod(a,n-(now/10)+1));
else ans=mul(ans,quick_mod(a,now-(now/10)));
}
cout<<ans.m[0][0]%mod<<endl;
}