zoukankan      html  css  js  c++  java
  • hdu 4291 A Short problem

    http://acm.hdu.edu.cn/showproblem.php?pid=4291

      一道矩阵快速幂的题目,给出递推关系,求目标函数的值。

      对递推的题比较陌生,刚开始的时候直接将快速幂套进去,过了sample以后就果断交上去了,没想到居然wa了。搞了一段时间,认真检查了代码无数次,还是找不到问题。

      然后突然被我想到一个相当大的问题。在直接暴力算的时候,算出一层的结果是已经取模以后的结果,可是题目要的是最终结果取模,如果直接套进去算就会发生偏差。对于最外面一层的的结果模10^9+7,我们需要找到这一层的循环节,曾而降低里面那层得到结果的数据规模。暴力打表,得出最外面一层的循环节大小是222222224。这样还没完,因为求解中有3层,所以我们需要继续求循环节,求得最里面一层的循环节长度是183120。然后,把它们建立成表,做成非递归的形式迭代求解。

    代码如下:

    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <algorithm>
      5 
      6 using namespace std;
      7 typedef __int64 ll;
      8 const int mod[3] = {1000000007, 222222224, 183120};
      9 const int matSize = 2;
     10 int curMod;
     11 
     12 struct Matrix {
     13     ll val[matSize][matSize];
     14 
     15     Matrix(bool Init = false) {
     16         for (int i = 0; i < matSize; i++) {
     17             for (int j = 0; j < matSize; j++) {
     18                 val[i][j] = 0;
     19             }
     20             if (Init) val[i][i] = 1;
     21         }
     22     }
     23 
     24 
     25     void print() {
     26         for (int i = 0; i < matSize; i++) {
     27             for (int j = 0; j < matSize; j++) {
     28                 printf("%I64d ", val[i][j]);
     29             }
     30             puts("");
     31         }
     32         puts("~~~");
     33     }
     34 } Base;
     35 
     36 Matrix operator * (Matrix _a, Matrix _b) {
     37     Matrix ret = Matrix();
     38 
     39     for (int i = 0; i < matSize; i++) {
     40         for (int k = 0; k < matSize; k++) {
     41             if (_a.val[i][k]) {
     42                 for (int j = 0; j < matSize; j++) {
     43                     ret.val[i][j] += (_a.val[i][k] * _b.val[k][j]) % curMod;
     44                     ret.val[i][j] %= curMod;
     45                 }
     46             }
     47         }
     48     }
     49 
     50     return ret;
     51 }
     52 
     53 Matrix operator ^ (Matrix _a, ll _p) {
     54     Matrix ret = Matrix(true);
     55 
     56     while (_p) {
     57         if (_p & 1) {
     58             ret = ret * _a;
     59         }
     60         _a = _a * _a;
     61         _p >>= 1;
     62     }
     63 
     64     return ret;
     65 }
     66 
     67 void initBase(ll _k = 1, ll _a = 3) {
     68     Base.val[0][1] = _k;
     69     Base.val[1][1] = _a;
     70     Base.val[0][0] = 0;
     71     Base.val[1][0] = 1;
     72 }
     73 
     74 ll fun(ll _x, int modKind) {
     75     Matrix ret = Matrix();
     76 
     77     curMod = mod[modKind];
     78     ret.val[0][0] = 0;
     79     ret.val[0][1] = 1;
     80 
     81     ret = ret * (Base ^ _x);
     82 //    ret.print();
     83 
     84     return ret.val[0][0];
     85 }
     86 
     87 ll deal(ll _x) {
     88     ll ret = _x;
     89 
     90     for (int i = 2; i >= 0; i--) {
     91         ret = fun(ret, i);
     92     }
     93 
     94     return ret;
     95 }
     96 
     97 int main() {
     98     ll n;
     99 //    Matrix tmp = Matrix(true);
    100 
    101     initBase();
    102 //    Base.print();
    103     /*
    104     for (ll i = 0; ; i++) {
    105         int last = tmp.val[0][0];
    106 
    107         tmp = tmp * Base;
    108         if (last == 0 && tmp.val[0][0] == 1) {
    109             printf("reach %I64d\n", i);
    110         }
    111     }
    112     */
    113     while (~scanf("%I64d", &n)) {
    114         printf("%I64d\n", deal(n));
    115     }
    116 
    117     return 0;
    118 }

    ——written by Lyon

  • 相关阅读:
    奇数阶魔方问题
    《DSP using MATLAB》示例9.3
    《DSP using MATLAB》示例9.2
    《DSP using MATLAB》示例9.1
    找个目标很重要
    《DSP using MATLAB》示例Example 8.30
    《DSP using MATLAB》示例Example 8.29
    《DSP using MATLAB》示例Example 8.28
    《DSP using MATLAB》示例Example 8.27
    《DSP using MATLAB》示例Example 8.26
  • 原文地址:https://www.cnblogs.com/LyonLys/p/hdu_4291_Lyon.html
Copyright © 2011-2022 走看看