hdu 1588 求f(b) +f(k+b) +f(2k+b) +f((n-1)k +b) 之和 (矩阵快速幂)

g(i)=k*i+b; 0<=i<n
f(0)=0
f(1)=1
f(n)=f(n-1)+f(n-2) (n>=2)
求f(b) +f(k+b) +f(2*k+b) +f((n-1)*k +b) 之和

Sample Input
2 1 4 100 // k b n MOD
2 0 4 100

Sample Output
21
12

矩阵A      相当于

1 1          f(2)  f(1)

1 0          f(1)  f(0)

| 1       1| ^b          | f(b+1)    f(b)|

mat^b =|1       0 |          =  | f(b)    f(b-1)|

求f(n) 就是求矩阵A的n次幂 再取第1行第2列的元素

要求的东西可化成  A^b*( I + A^k + (A^k)^2 + .... + (A^k)^(N-1) )

矩阵ans1 = A^b

矩阵B = A^k

矩阵C =

B  I

O  I

C的n次幂后  再取右上的小矩阵  就是I+B+B^2....+B^(n-1)  赋给ans2

ans1 * ans  再取第1行第2列的元素 就是最终答案

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cstring>
 4 # include <algorithm>
 5 # include <cmath>
 6 # define LL long long
 7 using namespace std ;
 8
 9 LL MOD ;
10
11 struct Matrix
12 {
13     LL mat[6][6];
14 };
15
16 Matrix mul(Matrix a,Matrix b, int n)
17 {
18     Matrix c;
19     for(int i=0;i<n;i++)
20         for(int j=0;j<n;j++)
21         {
22             c.mat[i][j]=0;
23             for(int k=0;k<n;k++)
24             {
25                 c.mat[i][j]=(c.mat[i][j] + a.mat[i][k]*b.mat[k][j])%MOD;
26             }
27         }
28     return c;
29 }
30 Matrix pow_M(Matrix a,int k , int n)
31 {
32     Matrix ans;
33     memset(ans.mat,0,sizeof(ans.mat));
34     for (int i=0;i<n;i++)
35         ans.mat[i][i]=1;
36     Matrix temp=a;
37     while(k)
38     {
39         if(k&1)ans=mul(ans,temp,n);
40         temp=mul(temp,temp,n);
41         k>>=1;
42     }
43     return ans;
44 }
45
46
47
48 int main ()
49 {
50     //freopen("in.txt","r",stdin) ;
51     Matrix A ;
52     A.mat[0][0] = A.mat[0][1] = A.mat[1][0] = 1 ;
53     A.mat[1][1] = 0 ;
54     int n , k , b ;
55     while(cin>>k>>b>>n>>MOD)
56     {
57         int i ,j ;
58         Matrix ans1 , ans2;
59         ans1 = pow_M(A,b,2) ;
60
61         Matrix B , C ;
62         B = pow_M(A,k,2) ;
63         memset(C.mat,0,sizeof(C.mat));
64         for (i = 0 ; i < 2 ; i++) //扩展成4 * 4的矩阵C
65         {
66             for (j = 0 ; j < 2 ; j++)
67             {
68                 C.mat[i][j] = B.mat[i][j] ;
69             }
70             C.mat[2+i][2+i] = 1 ;
71             C.mat[i][2+i] = 1 ;
72         }
73         ans2 = pow_M(C,n,4) ; // 4*4
74
75         ans2.mat[0][0] = ans2.mat[0][2] ;
76         ans2.mat[0][1] = ans2.mat[0][3] ;
77         ans2.mat[1][0] = ans2.mat[1][2] ;
78         ans2.mat[1][1] = ans2.mat[1][3] ;
79         ans1 = mul(ans1,ans2,2) ;
80
81         cout<<ans1.mat[0][1]%MOD<<endl ;
82     }
83
84     return 0 ;
85 }

时间: 2024-11-03 21:12:32

hdu 1588 求f(b) +f(k+b) +f(2k+b) +f((n-1)k +b) 之和 (矩阵快速幂)的相关文章

矩阵快速幂 HDU 4565 So Easy!(简单?才怪!)

题目链接 题意: 思路: 直接拿别人的图,自己写太麻烦了~ 然后就可以用矩阵快速幂套模板求递推式啦~ 另外: 这题想不到或者不会矩阵快速幂,根本没法做,还是2013年长沙邀请赛水题,也是2008年Google Codejam Round 1A的C题. #include <bits/stdc++.h> typedef long long ll; const int N = 5; int a, b, n, mod; /* *矩阵快速幂处理线性递推关系f(n)=a1f(n-1)+a2f(n-2)+.

HDU - 1588 Gauss Fibonacci (矩阵快速幂+二分求等比数列和)

Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r a very clever boy. So if you wanna me be your GF, you should solve the problem called GF~. " How good an opportunity that Gardon can not give up! The "Prob

HDU 2485 求删最少点使得 边权=1的有向图最短路&gt;k

题意: 给定n个点 m条有向边 k 下面m条有向边 问删最少几个点使得1-n的最短路>k 10 11 5 1 2 2 3 3 4 4 5 5 10 2 9 1 6 6 7 7 8 8 9 9 10 8 10 5 1 2 2 3 3 4 4 5 5 6 6 8 1 7 7 8 4 7 7 4 #include <stdio.h> #include <string.h> #define N 55 #define INF 1<<30 #define eps 1e-5 i

hdu 1575 求一个矩阵的k次幂 再求迹 (矩阵快速幂模板题)

Problem DescriptionA为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input数据的第一行是一个T,表示有T组数据.每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据.接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容. Output对应每组数据,输出Tr(A^k)%9973. Sample Input22 21 00 13 999999991 2 34

hdu 1588 Gauss Fibonacci(矩阵快速幂)

Gauss Fibonacci Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2090    Accepted Submission(s): 903 Problem Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r

hdu 3221 Brute-force Algorithm(快速幂取模,矩阵快速幂求fib)

http://acm.hdu.edu.cn/showproblem.php?pid=3221 一晚上搞出来这么一道题..Mark. 给出这么一个程序,问funny函数调用了多少次. 我们定义数组为所求:f[1] = a,f[2] = b, f[3] = f[2]*f[3]......f[n] = f[n-1]*f[n-2].对应的值表示也可为a^1*b^0%p,a^0*b^1%p,a^1*b^1%p,.....a^fib[n-3]*b^fib[n-2]%p.即a,b的指数从n=3以后与fib数列

HDU 1588 Gauss Fibonacci(矩阵快速幂+二分等比序列求和)

HDU 1588 Gauss Fibonacci(矩阵快速幂+二分等比序列求和) ACM 题目地址:HDU 1588 Gauss Fibonacci 题意: g(i)=k*i+b;i为变量. 给出k,b,n,M,问( f(g(0)) + f(g(1)) + ... + f(g(n)) ) % M的值. 分析: 把斐波那契的矩阵带进去,会发现这个是个等比序列. 推倒: S(g(i)) = F(b) + F(b+k) + F(b+2k) + .... + F(b+nk) // 设 A = {1,1,

hdu 2157 从a点走到b点刚好k步的方案数是多少 (矩阵快速幂)

n个点 m条路 询问T次 从a点走到b点刚好k步的方案数是多少 给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值把 给定的图转为邻接矩阵,即A(i,j)=1当且仅当存在一条边i->j.令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),实际上就 等于从点i到点j恰好经过2条边的路径数(枚举k为中转点).类似地,C*A的第i行第j列就表示从i到j经过3条边的路径数 Sample Input4 4 // n m0 10 21 32 32 //T0 3 2

HDOJ Queuing 2604【求矩阵+矩阵快速幂】

Queuing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3528    Accepted Submission(s): 1590 Problem Description Queues and Priority Queues are data structures which are known to most computer

HDU 5895 矩阵快速幂+高次幂取模

HDU 5895 Mathematician QSC 题意:已知f(n)=2*f(n-1)+f(n-2), g(n)=∑f(i)²(0<=i<=n), 给出n,x,y,s, 求x^(g(n*y))%(s+1); 思路:OEIS查到了g(n)=f(n)*f(n+1)/2, f(n)可以用矩阵快速幂求得, 有一个定理可以用于高次幂取模 x^n %k=x^(n%phi(k)+phi(k)) %k, 此处phi(x)为欧拉函数,但是在对幂次取模时存在一个除2, 又因为(a/b)%k=(a%bk)/b,