首页 > 代码库 > HDU - 1757 A Simple Math Problem (构造矩阵)

HDU - 1757 A Simple Math Problem (构造矩阵)

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 * f(x-3) + …… + a9 * f(x-10);
And ai(0<=i<=9) can only be 0 or 1 .

Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.
 

Input

The problem contains mutiple test cases.Please process to the end of file.
In each case, there will be two lines.
In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 )
In the second line , there are ten integers represent a0 ~ a9.
 

Output

For each case, output f(k) % m in one line.
 

Sample Input

10 9999 1 1 1 1 1 1 1 1 1 1 20 500 1 0 1 0 1 0 1 0 1 0
 

Sample Output

45 104
 题意:求f(k)%m
思路:还是构造矩阵跟HDU-2604类似
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 10;

int n, m;
struct Matrix {
	int v[maxn][maxn];
	Matrix() {}
	Matrix(int x) {
		init();
		for (int i = 0; i < maxn; i++) 
			v[i][i] = x;
	}
	void init() {
		memset(v, 0, sizeof(v));
	}
	Matrix operator *(Matrix const &b) const {
		Matrix c;
		c.init();
		for (int i = 0; i < maxn; i++)
			for (int j = 0; j < maxn; j++)
				for (int k = 0; k < maxn; k++)
					c.v[i][j] = (c.v[i][j] + (v[i][k]*b.v[k][j])%m) % m;
		return c;
	}
	Matrix operator ^(int b) {
		Matrix a = *this, res(1);
		while (b) {
			if (b & 1)
				res = res * a;
			a = a * a;
			b >>= 1;
		}
		return res;
	}
} a, b, tmp;

int main() {
	while (scanf("%d%d", &n, &m) != EOF) {
		a.init();
		for (int i = 1; i < 10; i++)
			a.v[i][i-1] = 1;
		for (int i = 0; i < 10; i++)
			scanf("%d", &a.v[0][i]);
		if (n < 10) {
			printf("%d\n", n%m);
			continue;
		}
		tmp = a^(n-9);
		int ans = 0;
		for (int i = 0; i < 10; i++)
			ans = (ans + tmp.v[0][i]*(9-i)) % m;
		printf("%d\n", ans);
	}
	return 0;
}