码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 10870 - Recurrences(矩阵快速幂)

时间:2014-07-21 09:30:29      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:style   http   color   os   io   for   

UVA 10870 - Recurrences

题目链接

题意:f(n) = a1 f(n - 1) + a2 f(n - 2) + a3 f(n - 3) + ... + ad f(n - d), for n > d.
已知前d项求第n项

思路:矩阵快速幂,对应矩阵为
|a1 a2 a3 ... ad|
|1 0 0 ... 0 0 0|
|0 1 0 ... 0 0 0|
|0 0 1 ... 0 0 0|
|0 0 0 ... 0 0 0|
|0 0 0 ... 1 0 0|
|0 0 0 ... 0 1 0|
|0 0 0 ... 0 0 1|

代码:

#include <stdio.h>
#include <string.h>

const int N = 20;
long long d, n, m, f[N];

struct mat {
	long long n, v[N][N];
	mat(long long n = 0) {
		this->n = n;
   		memset(v, 0, sizeof(v));
   	}
	mat operator * (mat b) {
		mat ans = mat(n);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				for (int k = 0; k < n; k++) {
					ans.v[i][j] = ((ans.v[i][j] + v[i][k] * b.v[k][j] % m) % m + m) % m;
    			}
   			}
  		}
  		return ans;
 	}
};

mat pow_mod(mat a, long long k) {
	mat ans(a.n);
	for (int i = 0; i < ans.n; i++)
		ans.v[i][i] = 1;
	while (k) {
		if (k&1) ans = ans * a;
		a = a * a;
		k >>= 1;
	}
	return ans;
}

int main() {
	while (~scanf("%lld%lld%lld", &d, &n, &m) && d) {
		mat a = mat(d);
		for (int i = 0; i < d; i++)
			scanf("%lld", &a.v[0][i]);
		for (int i = 1; i < d; i++)
			a.v[i][i - 1] = 1;
		for (int i = 0; i < d; i++)
			scanf("%lld", &f[i]);
		if (n <= d) printf("%lld\n", f[n - 1]);
		else {
			long long ans = 0;
			a = pow_mod(a, n - d); 
			for (int i = 0; i < d; i++)
				ans = (ans + (f[d - i - 1] * a.v[0][i] % m + m)) % m;
  			printf("%lld\n", ans);
  		}
 	}
	return 0;
}


UVA 10870 - Recurrences(矩阵快速幂),布布扣,bubuko.com

UVA 10870 - Recurrences(矩阵快速幂)

标签:style   http   color   os   io   for   

原文地址:http://blog.csdn.net/accelerator_/article/details/37990589

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!