码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 2326 数学作业

时间:2016-09-26 21:30:24      阅读:97      评论:0      收藏:0      [点我收藏+]

标签:

矩阵快速幂。

#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 数学作业

标签:

原文地址:http://www.cnblogs.com/ziliuziliu/p/5910499.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!