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\n", 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 }

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

时间: 2024-12-20 09:14:18

fzu Problem 2198 快来快来数一数 (快速幂+优化)的相关文章

poj 3734 方块涂色 求红色 绿色方块都为偶数的方案数 (矩阵快速幂)

N个方块排成一列 用红,蓝,绿,黄4种颜色去涂色,求红色方块 和绿色方块个数同时为偶数的 方案数 对10007取余 Sample Input 212Sample Output 2//(蓝,黄)6//(红红,蓝蓝,蓝黄,绿绿,黄蓝,黄黄) 1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <map>

HDU 3240 Counting Binary Trees(组合数学-斯特林数,数论-整数快速幂,数论-求逆元)

Counting Binary Trees Problem Description There are 5 distinct binary trees of 3 nodes: Let T(n) be the number of distinct non-empty binary trees of no more than n nodes, your task is to calculate T(n) mod m. Input The input contains at most 10 test

acdream 1060 递推数 (矩阵快速幂+循环节)

链接:click here~~ 题意: 递推数 Problem Description 已知A(0) = 0 , A(1) = 1 , A(n) = 3 * A(n-1) + A(n-2) (n ≥ 2)    求 A(A(A(A(N)))) Mod (1e9 + 7) Input 第一行一个整数 T (T ≤ 10000) 代表数据组数 每组数据占一行,一个整数 n (1 ≤ n ≤ 1e12) Output 对于每组测试数据输出一个整数. Sample Input 4 1 23574 278

hdu1757-- A Simple Math Problem(矩阵快速幂优化)

A Simple Math Problem Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Lele now is thinking about a simple function f(x). If x < 10 f(x) = x. If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2

随手练——麦森数(高精度快速幂)

https://www.luogu.org/problemnew/show/P1045 第一步:求位数 第二步:高精度快速幂的实现 第一版: 用vector做的,中间把超过500位的去除,但是实际跑起来比较慢 #include <iostream> #include <stdio.h> #include <math.h> #include <vector> #include <algorithm> using namespace std; int

OpenGL快问快答

OpenGL快问快答 本文内容主要来自对(http://www.opengl.org/wiki/FAQ)的翻译,随机加入了本人的观点.与原文相比,章节未必完整,含义未必雷同,顺序未必一致.仅供参考. 我写这个是为了加深印象,好记性不如烂笔头,好记星不如烂键盘. +BIT祝威+悄悄在此留下版了个权的信息说: 名词术语 渲染:等于"画",等于"draw". OpenGL是什么? OpenGL是Open Graphics Library(开源图形库)的缩写.它是一本说明书

FZu Problem 2236 第十四个目标 (线段树 + dp)

题目链接: FZu  Problem 2236 第十四个目标 题目描述: 给出一个n个数的序列,问这个序列内严格递增序列有多少个?不要求连续 解题思路: 又遇到了用线段树来优化dp的题目,线段树节点里面保存所表达区间里面的方案数.先离散化序列(升序排列),建树,然后按照没有sort前的顺序向线段树里面加点,每次查询小于该数的方案数目+1, 就是当前节点插入进去能影响的方案数目.在线段树对应位置加上新增加的数目即可. 1 #include <cstdio> 2 #include <queu

FZU Problem 2200 cleaning dp

Problem Description N个人围成一圈在讨论大扫除的事情,需要选出K个人.但是每个人与他距离为2的人存在矛盾,所以这K个人中任意两个人的距离不能为2,他们想知道共有多少种方法. Input 第一行包含一个数T(T<=100),表示测试数据的个数. 接下来每行有两个数N,K,N表示人数,K表示需要的人数(1<=N<=1000,1<=K<=N). Output 输出满足题意的方案数,方案数很大,所以请输出方案数mod 1,000,000,007 后的结果. Sam

FZU Problem 2171 防守阵地 II (线段树,区间更新)

 Problem 2171 防守阵地 II Accept: 143    Submit: 565Time Limit: 3000 mSec    Memory Limit : 32768 KB  Problem Description 部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵的能力之和.随着时间的推移,指挥部将下达Q个指令来替换M个进行防守的士兵们,每个参加完防守