2326: [HNOI2011]数学作业
Time Limit:10 Sec Memory Limit: 128 MBSubmit: 2067 Solved: 1205
[Submit][Status][Discuss]
Description
矩阵乘法加速递推
话说我这变量名绝壁充满逼格‘intermediary’
#include<cmath>
#include<ctime>
#include<cstdio>
#include<climits>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return f*x;
}
ll n,m;
struct matrix{ll m[3][3];}ans,intermediary;
matrix operator *(matrix a,matrix b)
{
matrix temp;memset(temp.m,0,sizeof(temp.m));
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
(temp.m[i][j]+=a.m[i][k]*b.m[k][j])%=m;
return temp;
}
void qpow(ll t,ll x)
{
intermediary.m[0][0]=t%m;intermediary.m[0][1]=0;intermediary.m[0][2]=0;
intermediary.m[1][0]=1;intermediary.m[1][1]=1;intermediary.m[1][2]=0;
intermediary.m[2][0]=1;intermediary.m[2][1]=1;intermediary.m[2][2]=1;
x=x-t/10+1;while(x)
{
if(x&1)ans=ans*intermediary;
intermediary=intermediary*intermediary;
x>>=1;
}
}
int main()
{
n=read();m=read();
ans.m[0][0]=1;ans.m[0][1]=0;ans.m[0][2]=0;
ans.m[1][0]=0;ans.m[1][1]=1;ans.m[1][2]=0;
ans.m[2][0]=0;ans.m[2][1]=0;ans.m[2][2]=1;
ll t=10;
while(t<=n)
{
qpow(t,t-1);
t*=10;
}
qpow(t,n);
printf("%d\n",ans.m[2][0]);
}