zoukankan      html  css  js  c++  java
  • HDU2971_Tower_求递推式累加

    这道题目够囧,表示公式推了大半天,有一个弯比较难想到。最后推出了公式,代码实现我是实现

    得一团糟,出现了几个wa,不过最终被我排查出来了,开心~

    /*
    *State:
    *题目大意:
    *        先假设a2 = t, 题目给定了递推关系:An = 2 * t * An-1 - An-2 (n > 2),
    *        初值A1 = 1, A2 = t;题目要求Sn = An ^ 2 + An-1 ^ 2 + ... + A1 ^ 2。
    *解题思路:
    *        Sn = An ^ 2 + Sn-1由这个,找出技巧(要推二次)
    *        化出:
    *            Sn = 4*k^2Sn-1 + (2-8*k^2)Sn-2 + 4*k^2Sn-3 - Sn-4;
    *        有了递推式,直接矩阵构造求解吧。
    *解题感想:
    *        这道题目很容易TLE,还有注意中间结果溢出问题。wa了3次,找了
    *        好久问题,最终还是化简了程序得到ac的,挺不容易,但是爽。
    */
    View Code
      1 #include <iostream>
      2 #include <cmath>
      3 #define maxn 5
      4 
      5 using namespace std;
      6 
      7 struct Mat
      8 {
      9     int m, n;
     10     __int64 d[maxn][maxn];
     11     void init(int m, int n) 
     12     {
     13         this->m = m;
     14         this->n = n;
     15         memset(d, 0, sizeof(d));
     16     }
     17     void initE(int size)                              //生成单位阵
     18     {
     19         m = n = size;
     20         for(int i = 0; i < n; i ++)
     21         {
     22             for(int j = 0; j < n; j ++)
     23             {
     24                 d[i][j] = i==j;
     25             }
     26         }
     27     }
     28 
     29     Mat operator * (const Mat & mat) const
     30     {
     31         static Mat res;
     32         res.init(m, mat.n);
     33         for(int i = 0; i < res.m; i ++)
     34         {
     35             for(int k = 0; k < n; k ++)
     36             {
     37                 if(d[i][k]==0)    continue;
     38                 for(int j = 0; j < res.n; j ++)
     39                 {
     40                     res.d[i][j] += d[i][k] * mat.d[k][j];
     41                 }
     42             }
     43         }
     44         return res;
     45     }
     46 
     47     Mat mul_mod(const Mat & mat, int mod) const
     48     {
     49         static Mat res;
     50         res.init(m, mat.n);
     51         for(int i = 0; i < res.m; i ++)
     52         {
     53             for(int k = 0; k < n; k ++)
     54             {
     55                 if(d[i][k]==0)    continue;
     56                 for(int j = 0; j < res.n; j ++)
     57                 {
     58                     res.d[i][j]=(res.d[i][j]+d[i][k]*mat.d[k][j]) % mod;
     59                 }
     60             }
     61         }
     62         return res;
     63     }
     64 
     65     void pow_mod(int k, int mod)                      //this = this^k % mod;
     66     {
     67         static Mat a;
     68         a = *this;
     69         for(this->initE(n); k; k>>=1, a=a.mul_mod(a, mod))
     70             if(k&1)    *this=this->mul_mod(a, mod);
     71     }
     72     
     73     //Mat pow_mod(int k, int mod) {                //不破坏原矩阵的版本
     74     //    static Mat a, r;
     75     //    for(a = *this, r.initE(n); k; k>>=1, a=a.mul_mod(a, mod))
     76     //        if(k&1)    r=r.mul_mod(a, mod);
     77     //    return r;
     78     //}
     79     
     80     void view_arr()
     81     {
     82         for(int i = 0; i < m; i++)
     83         {
     84             for(int j = 0; j < n; j++)
     85                 cout << d[i][j] << " ";
     86             cout << endl;
     87         }
     88     }
     89 };
     90 
     91 
     92 int main(void)
     93 {
     94 #ifndef ONLINE_JUDGE
     95     freopen("in.txt", "r", stdin);
     96 #endif
     97     int n, cas;
     98     __int64 mod, k;
     99     scanf("%d", &cas);
    100     while(cas--)
    101     {
    102         scanf("%I64d %d", &k, &n);
    103         scanf("%I64d", &mod);
    104         __int64 s[5], a3, a4;
    105 
    106         s[1] = 1, s[2] = (s[1] + (k * k)) % mod;
    107         a3 = (2 * k * k - 1) % mod;
    108         s[3] = ((a3 * a3) % mod + s[2]) % mod;
    109         a4 = (2 * k * a3 - k) % mod;
    110         s[4] = ((a4 * a4) % mod + s[3]) % mod;
    111 
    112         if(n <= 4)
    113         {
    114             printf("%I64d\n", s[n]);
    115             continue;
    116         }
    117 
    118         __int64 b1, b2, b3, b4;
    119 
    120         b1 = (4 * k * k) % mod;
    121         b2 = (2 - (8 * k * k)) % mod;  // 负数取模、、悬
    122         b3 = b1;
    123         b4 = -1;
    124 
    125         Mat a;
    126         a.init(4, 4);
    127         a.d[0][0] = b1, a.d[0][1] = b2, a.d[0][2] = b3, a.d[0][3] = b4;
    128         a.d[1][0] = 1, a.d[2][1] = 1, a.d[3][2] = 1;
    129         a.view_arr();
    130         a.pow_mod(n - 4, mod);
    131         cout << "hah" << endl;
    132         a.view_arr();
    133         __int64 ans = ((a.d[0][0] * s[4]) % mod + (a.d[0][1] * s[3]) % mod
    134                 + (a.d[0][2] * s[2]) % mod + (a.d[0][3] * s[1]) % mod) % mod;
    135 
    136         printf("%I64d\n", ((ans % mod) + mod) % mod);
    137     }
    138     return 0;
    139 }

    跑了4000+ms,这个鸭梨比较大,该题很容易TLE,小心了。

  • 相关阅读:
    李宏毅2021春机器学习课程笔记——通过训练集上的Loss可获得的信息
    python学习-NotImplementedError的使用
    代码运行优化
    django实现上传文件读取文件内容
    django-admin上传下载文件
    AtCoder Beginner Contest 191 F
    敏感词过滤 AC自动机
    面经知识点
    select poll epoll实例
    socket用法
  • 原文地址:https://www.cnblogs.com/cchun/p/2619545.html
Copyright © 2011-2022 走看看