• fzu Problem 2198 快来快来数一数 (快速幂+优化)


    题目链接:

      Problem  2198  快来快来数一数

    题目描述:

      给出n个六边形排成一排,a[i]代表i个六边形能组成的生成树个数,设定s[i]等于a[1]+a[2]+a[3]+....+a[i-1]+a[i],问s[n]为多少?

    解题思路:

      n取值范围[1, 1018],打表内存不够,然后就要考虑快速幂咯!纳尼!!!!快速幂写出来竟然超时,敢信?果然还是见题太少了。(GG)

      对于a[n] = 6*a[n-1] - a[n-2],可以很明显看出。

      然后求和的时候就要化简一番了,但是并不是很难,最终的公式是:s[n] = 6*s[n-1] - s[n-2] + 5;然后构造矩阵,预处理构造矩阵,跑快速幂即可!!

    代码:

     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <queue>
     7 #include <cstring>
     8 using namespace std;
     9 
    10 #define LL long long
    11 const LL maxn = 3;
    12 const LL mod = 1000000007;
    13 struct mat
    14 {
    15     LL col, row;
    16     LL p[maxn][maxn];
    17 } pp[65];
    18 
    19 mat mul (mat a, mat b);
    20 mat pow (LL n, LL res, mat b);
    21 
    22 int main ()
    23 {
    24     LL n, t;
    25     mat b;
    26     scanf ("%lld", &t);
    27     memset (pp[0].p, 0, sizeof(pp[0].p));
    28     memset (b.p, 0, sizeof(b.p));
    29     pp[0].col = pp[0].row = b.row = maxn;
    30     b.col = 1;
    31     pp[0].p[0][0] = 6;
    32     pp[0].p[1][0] = -1;
    33     pp[0].p[0][1] = pp[0].p[2][0] = pp[0].p[2][2] = 1;
    34     b.p[0][0] = 6;
    35     b.p[0][1] = 0;
    36     b.p[0][2] = 5;
    37     for (int i=1; i<65; i++)
    38         pp[i] = mul(pp[i-1], pp[i-1]);
    39         
    40     while (t --)
    41     {
    42         mat a;
    43         scanf ("%lld", &n);
    44         a = pow(n-1, 0, b);
    45         printf ("%lld
    ", a.p[0][0] % mod);
    46     }
    47     
    48     return 0;
    49 }
    50 
    51 mat mul (mat a, mat b)
    52 {
    53     mat c;
    54     c.col = a.col;
    55     c.row = b.row;
    56     memset (c.p, 0, sizeof(c.p));
    57     for (int k=0; k<a.row; k++)
    58         for (int i=0; i<a.col; i++)
    59         {
    60             if (a.p[i][k] == 0) continue;
    61             for (int j=0; j<b.row; j++)
    62             {
    63                 if (b.p[k][j] == 0) continue;
    64                 c.p[i][j] = (c.p[i][j] + a.p[i][k] * b.p[k][j] + mod) % mod;
    65             }
    66         }
    67     return c;
    68 }
    69 
    70 mat pow (LL n, LL res, mat b)
    71 {
    72     while (n)
    73     {
    74         if (n % 2)
    75             b = mul (b, pp[res]);
    76         res ++;
    77         n /= 2;
    78     }
    79     return b;
    80 }

    写的好丑!不要喷我 (捂脸逃~~~~)

    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    python入门之函数及其方法
    Python入门知识点2---字符串
    Python列表 元组 字典 以及函数
    Python入门知识
    Autofac使用代码
    优化EF以及登录验证
    CRM框架小知识以及增删查改逻辑代码
    分页SQL
    触发器SQL
    动态生成lambda表达式
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4859139.html
Copyright © 2020-2023  润新知