1. 程式人生 > >數綿羊(矩陣快速冪)

數綿羊(矩陣快速冪)

問題描述

一個數: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; }