首页 > 代码库 > BZOJ 2326 HNOI2011 数学作业 矩阵乘法
BZOJ 2326 HNOI2011 数学作业 矩阵乘法
题目大意:求1234567891011121314...n mod m 的值
设F(n)=1234567891011121314...n 那么显然有F(n)=F(n-1)*(floor(lgn)+1)+n
于是我们可以矩乘
将数字按照floor(lgn)+1分类
构造状态矩阵F(n) n+1 1 初值为0 1 1
1~9的转移矩阵为
10 0 0
1 1 0
0 1 1
10~99的转移矩阵为
100 0 0
1 1 0
0 1 1
以此类推
注意构造矩阵的时候要取模不然会挂
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef unsigned long long ll; struct Matrix{ ll xx[4][4]; Matrix(int flag) { int i,j; for(i=1;i<=3;i++) for(j=1;j<=3;j++) if(i==j) xx[i][j]=flag; else xx[i][j]=0; } Matrix(bool,ll digit) { xx[1][1]=digit; xx[2][1]=xx[2][2]=xx[3][2]=xx[3][3]=1; xx[1][3]=xx[1][2]=xx[2][3]=xx[3][1]=0; } ll* operator [] (int x) { return xx[x]; } }ans(1); ll n,p; void operator *= (Matrix &x,Matrix y) { int i,j,k; Matrix z(0); for(i=1;i<=3;i++) for(j=1;j<=3;j++) for(k=1;k<=3;k++) z[i][j]+=x[i][k]*y[k][j],z[i][j]%=p; x=z; } Matrix Quick_Power(Matrix x,ll y) { Matrix re(1); while(y) { if(y&1) re*=x; x*=x;y>>=1; } return re; } int main() { ll i; cin>>n>>p; for(i=10;i<=n;i*=10) ans*=Quick_Power(Matrix(true,i%p),i-i/10); ans*=Quick_Power(Matrix(true,i%p),n-i/10+1); cout<<(ans[2][1]+ans[3][1])%p<<endl; }
BZOJ 2326 HNOI2011 数学作业 矩阵乘法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。