Buses
题意:读入总长及k,l,分别代表小巴士和大巴士的颜色数,其中小巴长为5,大巴长为10,问用无数量小巴大巴排成长度为n一共有多少种可能
解法:矩阵乘法。可以写出递推式,先将n/5,f[1] = k; f[2] = k*k+l; f[i] = f[i-1]*k+f[i-2]*l;
求出f[n]为解,那么就可以用矩阵使得复杂度降到log级别
#include <iostream>
using namespace std;
#include <stdio.h>
#include <cstring>
const long long mo = 1000000;
long long f[60][3][3], n, k, l, ans, matrix[3][3], temp[3][3], t;
int main() {
while (scanf("%lld %lld %lld", &n, &k, &l) != EOF) {
n = n/5;
k = k%mo;
l = l%mo;
if (n == 1) ans = k%mo;
else if (n == 2) ans = (k*k+l)%mo;
else {
n = n-2;
memset(f, 0, sizeof(f));
memset(matrix, 0, sizeof(matrix));
f[0][1][2] = l;
f[0][2][1] = 1;
f[0][2][2] = k;
t = 1;
int x = 0;
while (1) {
if (t*2 > n) break;
t = t*2;
x++;
for (int i = 1; i <= 2; i++)
for (int j = 1; j <= 2; j++)
for (int k = 1; k <= 2; k++)
f[x][i][j] = (f[x][i][j]+f[x-1][i][k]*f[x-1][k][j])%mo;
}
matrix[1][1] = 1;
matrix[2][2] = 1;
for (int p = x; p >= 0; p--) {
if (n >= t) {
n = n-t;
memset(temp, 0, sizeof(temp));
for (int i = 1; i <= 2; i++)
for (int j = 1; j <= 2; j++)
for (int k = 1; k <= 2; k++)
temp[i][j] = (temp[i][j]+matrix[i][k]*f[p][k][j])%mo;
for (int i = 1; i <= 2; i++)
for (int j = 1; j <= 2; j++)
matrix[i][j] = temp[i][j];
}
t = t/2;
}
ans = (k*matrix[1][2]+(k*k+l)*matrix[2][2])%mo;
}
if (ans < 100000) cout << 0;
if (ans < 10000) cout << 0;
if (ans < 1000) cout << 0;
if (ans < 100) cout << 0;
if (ans < 10) cout << 0;
cout << ans << endl;
}
}