HDU3306 -- Another kind of Fibonacci 构造矩阵然后矩阵快速幂

Another kind of Fibonacci

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2428    Accepted Submission(s): 963


Problem Description
As we all known , the Fibonacci series : F(0) = 1, F(1) = 1, F(N) = F(N - 1) + F(N - 2) (N >= 2).Now we define another kind of Fibonacci : A(0) = 1 , A(1) = 1 , A(N) = X * A(N - 1) + Y * A(N - 2) (N >= 2).And we want to Calculate S(N) , S(N) = A(0) 2 +A(1) 2+……+A(n) 2.

 

Input
There are several test cases.
Each test case will contain three integers , N, X , Y .
N : 2<= N <= 2 31 – 1
X : 2<= X <= 2 31– 1
Y : 2<= Y <= 2 31 – 1
 

Output
For each test case , output the answer of S(n).If the answer is too big , divide it by 10007 and give me the reminder.
 

Sample Input
  
  
2 1 1 3 2 3
 

Sample Output
  
  
6 196
 

Author
wyb
 

Source
 

Recommend
wxl


此题关键就在于构造矩阵,构造的矩阵如下:
很显然我们先推s[n]=s[n-1]+A[n]^2;A[n]^2=x*x*A[n-1]^2+y*y*A[n-2]^2+2*x*y*A[n-1][n-2];于是我们发现又涉及到了A[n-1]*A[n-2]。A[n]*A[n-1]=x*A[n-1]^2+y*A[n-1]*A[n-2];

|2  1  1  1|   |1         0         0   0|  =  |f(n)       A(n)^2      A(n)*A(n-1)     A(n-1)^2|
|0  0  0  0| * |x^2     x^2      x   1|  =  |  0        0               0                     0            |
|0  0  0  0|   |2*x*y   2*x*y   y   0|  =  |  0        0               0                     0            |
|0  0  0  0|   |y^2     y^2      0   0|  =  |  0        0               0                     0            |


AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;


const int maxm = 100002;
const int maxn = 100002;
const int inf = 0x3f3f3f3f;

int n, m, k;
struct node {
	int x, y, w;
};
node edge[maxm*2];
int book[maxn];
int main()
{
	while(~scanf("%d%d%d", &n, &m, &k)) {
		memset(book, 0, sizeof(book));
		int i;
		for(i=0; i<m; ++i)
			scanf("%d%d%d", &edge[i].x, &edge[i].y, &edge[i].w);
		if(!k) {
			printf("-1\n");
			continue;
		}
		int a;
		for(i=0; i<k; ++i) {
			scanf("%d", &a);
			book[a] = 1;
		}
		int ans = inf;
		for(i=0; i<m; ++i) {
			if(book[edge[i].x] + book[edge[i].y] == 1) {
				ans = min(ans, edge[i].w);
			}
		}
		if(ans == inf)
			printf("-1\n");
		else  printf("%d\n", ans);
	}
	
}
/*
|2  1  1  1|   |1       0        0   0| = |f(n)  A(n)^2  A(n)*A(n-1)  A(n-1)^2|
|0  0  0  0| * |x^2     x^2      x   1| = |  0     0         0            0   |
|0  0  0  0|   |2*x*y   2*x*y    y   0| = |  0     0         0            0   |
|0  0  0  0|   |y^2     y^2      0   0| = |  0     0         0            0   |
*/



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值