首页 > 代码库 > BZOJ 2326 数学作业

BZOJ 2326 数学作业

矩阵快速幂。

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;struct matrix{    long long a[4][4];    long long n,m;}a,b;long long n,m,l=1,r=10;long long mmul(long long a,long long b){    long long d=(long long)floor(a*(long double)b/m+0.5);    long long ret=a*b-d*m;    if (ret<0) ret+=m;    return ret;}void get_table(){    a.a[1][1]=0;a.a[1][2]=0;a.a[1][3]=1;    b.a[1][1]=1;b.a[1][2]=0;b.a[1][3]=0;    b.a[2][1]=1;b.a[2][2]=1;b.a[2][3]=0;    b.a[3][1]=1;b.a[3][2]=1;b.a[3][3]=1;}void modify(){    b.a[1][1]=(b.a[1][1]*10)%m;}matrix mul(matrix a,matrix b){    matrix c;    for (long long i=1;i<=3;i++)        for (long long j=1;j<=3;j++)            c.a[i][j]=0;    for (long long i=1;i<=3;i++)        for (long long j=1;j<=3;j++)            for (long long k=1;k<=3;k++)                c.a[i][j]=(c.a[i][j]+mmul(a.a[i][k],b.a[k][j])%m)%m;    return c;}void f_pow(matrix x,long long y){    matrix ans=x,base=b;    while (y)    {        if (y&1) ans=mul(ans,base);        base=mul(base,base);        y>>=1;    }    a=ans;}int main(){    scanf("%lld%lld",&n,&m);    get_table();    modify();    while (n>=r)    {        f_pow(a,r-l);        l*=10;r*=10;        modify();    }    f_pow(a,n-l+1);    printf("%lld\n",a.a[1][1]%m);    return 0;}

 

BZOJ 2326 数学作业