乍一看直接模拟,暴力递推,索性NK的数据比较水,过起来很容易
#include<iostream>
#include<string>
#include<string.h>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
using namespace std;
#define ll int
#define MAX 250
#define inf 10000000
#define mod 10000
int main() {
ll a0, a1, p, q, k;
while (cin >> a0 >> a1 >> p >> q >> k) {
ll cnt = 2, res = 0;
if (k == 0)cout << a0 << endl;
else if (k == 1)cout << a1 << endl;
else {
while (cnt <= k) {
res = (q * a0 % mod + p * a1 % mod) % mod;
a0 = a1, a1 = res; cnt++;
}
}
cout << res << endl;
}
}
但是这种题直接递推一般是过不了的出题人比较憨除外,这种类似于斐波那契数列的问题,一般都可以高效的转化为矩阵快速幂进行计算,一个详细教程
对公式
a
n
=
p
∗
a
(
n
−
1
)
+
q
∗
a
(
n
−
2
)
an=p*a(n-1) + q*a(n-2)
an=p∗a(n−1)+q∗a(n−2)
我们可以将他写作
这样的话我们进行和正常斐波那契数列一样的递推,就能得出(详细步骤见上面链接的教程)
#include<iostream>
#include<string>
#include<string.h>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
using namespace std;
#define ll int
#define MAX 250
#define inf 10000000
#define mod 10000
struct mat {
ll a[2][2];
mat operator * (mat m) {
mat res;
for (int i = 0; i < 2; i++)for (int j = 0; j < 2; j++)res.a[i][j] = 0;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < 2; k++)
res.a[i][j] = (res.a[i][j] + a[i][k] * m.a[k][j]) % mod;
return res;
}
};
mat quickPow(mat a, int k) {
mat res;//对角矩阵
res.a[0][0] = res.a[1][1] = 1; res.a[0][1] = res.a[1][0] = 0;
while (k > 0) {
if (k & 1) res = res * a;
a = a * a; k >>= 1;
}
return res;
}
int main() {
ll a0, a1, p, q, k;
while (cin >> a0 >> a1 >> p >> q >> k) {
ll cnt = 2, ans = 0;
if (k == 0)cout << a0 << endl;
else if (k == 1)cout << a1 << endl;
mat a; a.a[0][0] = p, a.a[0][1] = q, a.a[1][0] = 1, a.a[1][1] = 0;
mat res = quickPow(a, k - 1);
ans = ((res.a[0][0] * a1) % mod + (res.a[0][1] * a0) % mod) % mod;
cout << ans << endl;
}
}