题目描述
Given a number n, you should calculate 123456 . . . 11121314 . . . n module 11.
输入
A single line with an integer n (0 < n ≤ 10e18) 单组数据测试.
输出
Output one integer, 123456 . . . 11121314 . . . n module 11
样例输入
1
20
21
样例输出
1
5
4
提示
1 ≡ 1( mod 11)
1234567891011121314151617181920 ≡ 5( mod 11)
123456789101112131415161718192021 ≡ 4( mod 11)
矩阵快速幂模板。。以前敲几次 都是手敲,老是有小bug。还是存个模板吧。
matrix muliti(matrix x,matrix y){
matrix ret;
for(int i=0;i<3;++i)
for(int j=0;j<3;++j){
ret.a[i][j]=0;
for(int k=0;k<3;++k){
ret.a[i][j]+=(x.a[i][k]*y.a[k][j])%mod;
ret.a[i][j]%=mod;
}
}
return ret;
}
matrix ksm(matrix x,ll k){
matrix ret;
memset(ret.a,0,sizeof(ret.a));
ret.a[0][0]=ret.a[1][1]=ret.a[2][2]=1;
if(k==0) return ret;
if(k==1) return x;
if(k%2==0) {
ret=ksm(x,k/2);
return muliti(ret,ret);
}else{
ret=ksm(x,k-1);
return muliti(ret,x);
}
}
思路:
数非常非常大,大到存不下,但是给你了末尾,就能推出来。
设该数为Sn。 Sn=Sn-1*10^k+n-1;
很明显构造3*3的矩阵,
sn n -1
0 0 0
0 0 0
然后构造10^k矩阵。
因为k有18种,所以构造18种情况,
10^k 0 0
1 1 0
1 1 1
然后快速幂就行了。
#include<string>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int mod=11;
struct matrix{
int a[3][3];
}C[20],ans;
ll n,nn;
void init(){
ans.a[0][0]=ans.a[1][1]=ans.a[2][2]=1;
C[1].a[0][0]=10;
C[1].a[1][0]=C[1].a[2][0]=C[1].a[1][1]=C[1].a[2][1]=C[1].a[2][2]=1;
for(int i=2;i<20;++i){
C[i]=C[i-1];
C[i].a[0][0]*=10;
C[i].a[0][0]%=mod;
}
}
matrix muliti(matrix x,matrix y){
matrix ret;
for(int i=0;i<3;++i)
for(int j=0;j<3;++j){
ret.a[i][j]=0;
for(int k=0;k<3;++k){
ret.a[i][j]+=(x.a[i][k]*y.a[k][j])%mod;
ret.a[i][j]%=mod;
}
}
return ret;
}
matrix ksm(matrix x,ll k){
matrix ret;
memset(ret.a,0,sizeof(ret.a));
ret.a[0][0]=ret.a[1][1]=ret.a[2][2]=1;
if(k==0) return ret;
if(k==1) return x;
if(k%2==0) {
ret=ksm(x,k/2);
return muliti(ret,ret);
}else{
ret=ksm(x,k-1);
return muliti(ret,x);
}
}
int main(){
while(~scanf("%lld",&n)){
memset(ans.a,0,sizeof(ans.a));
nn=n;
int len=0;
while(nn){
nn/=10;
len++;
}
init();
ll k=1;
for(int i=1;i<len;++i){
ans=muliti(ans,ksm(C[i],k*9));
k*=10;
}
ans=muliti(ans,ksm(C[len],n-k+1));
printf("%d\n",ans.a[2][0]);
}
return 0;
}