记录编号 319891 评测结果 AAAAAAAAAA
题目名称 [HNOI 2011] 数学作业 最终得分 100
用户昵称 Gravatarsxysxy 是否通过 通过
代码语言 C++ 运行时间 0.007 s
提交时间 2016-10-11 13:33:35 内存使用 0.29 MiB
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <cstring>
#include <list>
#include <queue>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std; 

typedef long long LL;
LL MOD;
struct matrix
{
    int r, c;   //行 列 (宽 长)
    LL a[4][4];
    matrix(int sw = 3, int sh = 3)
    {
        r = sw;
        c = sh;
    }
    void sets(int sw, int sh)
    {
        r = sw;
        c = sh;
    }
    void std_matrix()
    {
        zero();
        for(int i = 1; i <= 3; i++)
            a[i][i] = 1;
    }
    void zero()
    {
        memset(a, 0, sizeof(a));
    }
    matrix operator*(matrix &o)
    {
        matrix res;
        res.sets(r, o.c);
        res.zero();
        for(int i = 1; i <= res.r; i++)
            for(int j = 1; j <= res.c; j++)
                for(int k = 1; k <= res.c; k++)
                {
                    res.a[i][j] += (a[i][k]%MOD)*(o.a[k][j]%MOD)%MOD;
                    res.a[i][j] %= MOD;
                }
        return res;
    }
    
};
LL ipow(LL base, int exp)
{
    LL ans = 1;
    while(exp)
    {
        if(exp & 1)
            ans = ans * base;
        exp >>= 1;
        base *= base;
    }
    return ans;
}
matrix fast_pow(matrix base, int exp)
{
    matrix ans;
    ans.std_matrix(); //单位矩阵
    while(exp)
    {
        if(exp & 1)
            ans = ans * base;
        exp >>= 1;
        base = base*base;
    }
    return ans;
}
matrix mmm;
matrix ans;
void calc(LL t ,LL x)
{
    mmm.zero();
    mmm.a[1][1] = t%MOD;
    mmm.a[1][2] = mmm.a[1][3] = 1;
    mmm.a[2][2] = mmm.a[2][3] = 1;
    mmm.a[3][3] = 1;
    for(LL y = x-t/10+1; y; y>>=1, mmm = mmm*mmm)
        if(y&1)
            ans = mmm*ans;
                //生无可恋的眼神...矩阵乘法不满足交换律之前写ans = ans*mmm无限WA调了1小时..
}
int main()
{
    freopen("mathwork.in", "r", stdin);
    freopen("mathwork.out", "w", stdout);
    LL n;
    scanf("%lld %lld", &n, &MOD);
    ans.std_matrix();
    LL t = 10;
    while(n >= t)
    {
        calc(t, t-1);
        t *= 10;
    }
    calc(t, n);
    printf("%lld\n", ans.a[1][3]);
    return 0;
}