zoukankan      html  css  js  c++  java
  • BZOJ 2326 数学作业

    题意:

    给出一个数字N(1e18),求1 ~ N 的数字排起来mod上M(<= 1e9)的值。

    题解:

    0.定义f[x]表示以数字x结尾的数字mod 上 M 的值。

    1.

      f[x] = f[x-1] * 10 + x - 1 + 1 x为个位数的情况

      f[x] = f[x-1] * 100 + x - 1 + 1 x为两位数的情况

      f[x] = f[x-1] * 1000 + x - 1 + 1 x为三位数的情况

      ......

    2.这样就可以对不同位数的数建立矩阵进行加速转移

    /**************************************************************
        Problem: 2326
        User: xgtao
        Language: C++
        Result: Accepted
        Time:24 ms
        Memory:1288 kb
    ****************************************************************/
     
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
     
    #define ll long long
    ll mod, n, pow[25];
     
    struct Matrix {
        ll map[3][3];
        void clear () { memset (map, 0, sizeof (map));}
    };
     
    Matrix MatrixMul (Matrix x, Matrix y) {
        Matrix ret;
        ret.clear();
        for (int i = 0; i < 3; ++i) 
            for (int j = 0;j < 3; ++j)
                for (int k = 0; k < 3; ++k)
                    ret.map[i][j] = (ret.map[i][j] + x.map[i][k] * y.map[k][j] % mod) % mod;
        return ret;
    }
     
    Matrix MatrixPow (Matrix x, ll n) {
        Matrix ret;
        ret.clear();
        ret.map[0][0] = ret.map[1][1] = ret.map[2][2] = 1;
        while (n) {
            if (n & 1) ret = MatrixMul(ret, x);
            x = MatrixMul(x, x);
            n >>= 1;
        }
        return ret;
    }
     
    Matrix calc (ll x, ll n) {
        Matrix ret;
        ret.clear();
        ret.map[0][0] = x % mod;
        ret.map[0][1] = 0;
        ret.map[0][2] = 0;
        ret.map[1][0] = 1;
        ret.map[1][1] = 1;
        ret.map[1][2] = 0;
        ret.map[2][0] = 1;
        ret.map[2][1] = 1;
        ret.map[2][2] = 1;
        return MatrixPow(ret, n);
    }
     
    int main () {
        pow[0] = 1;
        for (int i = 1; i <= 18; ++i) pow[i] = pow[i - 1] * 10;
        cin >> n >> mod;
        int cur = 1;
        Matrix ans;
        ans.clear();
        ans.map[0][0] = ans.map[1][1] = ans.map[2][2] = 1;
        while (true) {
            ll L = pow[cur - 1], R = min (n, pow[cur] - 1);
            ans = MatrixMul (ans, calc(pow[cur], R - L + 1));
            ++cur;
            if (R == n) break;
        }
        cout << ans.map[2][0] << endl;
        return 0;
    }
    

      

  • 相关阅读:
    数据库mysql的基本操作
    多进程多线程与进程池线程池及协程
    面对对象的属性和方法
    Python中的编码及操作文件
    通过pymysql操作mysql数据库
    Spring注入
    Mybatis标签及使用1
    全局配置文件说明
    类方法和对象方法的区别
    Mybatis
  • 原文地址:https://www.cnblogs.com/xgtao/p/5964527.html
Copyright © 2011-2022 走看看