zoukankan      html  css  js  c++  java
  • 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 }

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

    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    洛谷—— P3353 在你窗外闪耀的星星
    洛谷—— P1238 走迷宫
    洛谷—— P1262 间谍网络
    9.8——模拟赛
    洛谷—— P1189 SEARCH
    算法
    May 22nd 2017 Week 21st Monday
    May 21st 2017 Week 21st Sunday
    May 20th 2017 Week 20th Saturday
    May 19th 2017 Week 20th Friday
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4859139.html
Copyright © 2011-2022 走看看