递推
题目描述
JYM和XJ转眼就从小学上了高中。在学习递推的时候,JYM在纸上随手写了一个递推关系式:an=2*an-1,a0=0。写完这个递推式,JYM拿给XJ看,XJ觉得太过简单,于是大笔一挥,在等式右边又加了一个式子,变成了这样:an=2*an-1+n2。JYM看到这个式子,想要算几个项来看看,可是一算就发现这个数据量太大了,你能帮他解决这个问题吗?
输入描述:
输入数据有多组(不超过100组数据),每组数据包含一个整数N<=1018
输出描述:
一个整数X,表示递推式第n项的值。由于数字太大,因此结果对于1000000009取模后输出。
输入
0 1 2 3
输出
0 1 6 21
// a(n) = 2 * a(n - 1) + n^2 // a(n) = 2 * (2 * a(n - 2) + (n - 1)^2) + n^2 // a(n) = 2^2 * a(n - 2) + 2 * (n - 1)^2 + n^2 // a(n) = 2^n * a(0) + 2^(n - 1) * 1^2 + 2^(n - 2) * 2^2 + ... + 2^1 * (n - 1)^2 + 2^0 * n^2 // 通项2^i * (n - i)^2 for i in range(0, n + 1) // a(n) = 2 * a(n - 1) + (n - 1)^2 + 2 * (n - 1) + 1 #include<bits/stdc++.h> using namespace std; typedef long long LL; const LL MOD = 1e9 + 9; void mulself(LL a[4][4]) { LL c[4][4] = {0}; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { for (int k = 0; k < 4; k++) { c[i][j] = (c[i][j] + a[i][k] * a[k][j]) % MOD; } } } memcpy(a, c, sizeof(c)); } void mul(LL a[4][4], LL b[4][4]) { LL c[4][4] = {0}; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { for (int k = 0; k < 4; k++) { c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % MOD; } } } memcpy(a, c, sizeof(c)); } int main() { LL n; while (cin >> n) { LL ans[4][4] = {0}; LL a[4][4] = {{2, 1, 2, 1}, {0, 1, 2, 1}, {0, 0, 1, 1}, {0, 0, 0, 1}}; for (int i = 0; i < 4; i++) ans[i][i] = 1; while (n) { if (n & 1) mul(ans, a); mulself(a); n >>= 1; } cout << ans[0][3] << endl; } return 0; }

浙公网安备 33010602011771号