HNOI2011 数学作业 发表于 2018-08-09 | 分类于 各省省选 | 字数统计: 369 字 题目链接 题解1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cctype>using namespace std;typedef unsigned long long ll;ll n,Mod;struct Mat{ ll dat[3][3]; int r,c; Mat(int _r,int _c){ r=_r,c=_c; memset(this->dat,0,sizeof(this->dat)); }};Mat mul(Mat &a,Mat &b){ Mat newed(a.r,b.c); int i,j,k;ll t; for(i=0;i<a.r;i++) for(j=0;j<b.c;j++){ for(t=0,k=0;k<a.c;k++)t+=(a.dat[i][k])*(b.dat[k][j]),t%=Mod; newed.dat[i][j]=t%Mod; } return newed;}Mat Pow(Mat a,ll p){ Mat E(a.c,a.c); int i,j; for(i=0;i<a.c;i++) for(j=0;j<a.c;j++) E.dat[i][j]=(i==j)?1:0; while(p){ if(p&1)E=mul(E,a); a=mul(a,a),p>>=1; } return E;}void print(Mat q){ for(int i=0;i<q.r;i++){ for(int j=0;j<q.c;j++) printf("%llu ",q.dat[i][j]); printf("\n"); }}void init(){ scanf("%llu%llu",&n,&Mod); n++;}void solve(){ ll cur=1,nex=10; Mat Ori(1,3),Plu(3,3),Copy(3,3),res(3,3); Ori.dat[0][0]=Ori.dat[0][2]=1; Plu.dat[0][0]=Plu.dat[0][1]= Plu.dat[2][0]=Plu.dat[2][2]=1; Plu.dat[1][1]=10; for(;;){ Copy=Pow(Plu,min(nex,n)-cur); res=mul(Ori,Copy); if(nex>=n)break; Plu.dat[1][1]*=10,Plu.dat[1][1]%=Mod; cur*=10,nex*=10; Ori=res; } printf("%llu\n",res.dat[0][1]);}int main(){ init(); solve(); return 0;}