HDU1588-Gauss Fibonacci(矩阵高速幂+等比数列二分求和)
2017-04-18 20:16
447 查看
题目链接
题意:g(x) = k * x + b。f(x) 为Fibonacci数列。求f(g(x)),从x = 1到n的数字之和sum。并对m取模。
思路:
设A = |(1, 1),(1, 0)|
sum = f(b) + f(k + b) + f(2k + b)...+f((n-1)k + b) (f(x) 为Fibonacci数列)
sum = A^b + A^(k + b) + A^(2k + b)...+ A^((n-1)k + b)
sum = A^b(1 + A^k + A^2k...+A^(n-1)k)
所以A^b与A^k能够用矩阵高速幂求解
之后能够设B = A^k
所以式子能够转化为sum = A^b(1 + B + B^2..+ B^(n - 1))
sum就能够使用等比数列二分求和来攻克了。
代码:
题意:g(x) = k * x + b。f(x) 为Fibonacci数列。求f(g(x)),从x = 1到n的数字之和sum。并对m取模。
思路:
设A = |(1, 1),(1, 0)|
sum = f(b) + f(k + b) + f(2k + b)...+f((n-1)k + b) (f(x) 为Fibonacci数列)
sum = A^b + A^(k + b) + A^(2k + b)...+ A^((n-1)k + b)
sum = A^b(1 + A^k + A^2k...+A^(n-1)k)
所以A^b与A^k能够用矩阵高速幂求解
之后能够设B = A^k
所以式子能够转化为sum = A^b(1 + B + B^2..+ B^(n - 1))
sum就能够使用等比数列二分求和来攻克了。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; //typedef long long ll; typedef __int64 ll; const int N = 2; struct mat{ ll s ; mat(ll a = 0, ll b = 0, ll c = 0, ll d = 0) { s[0][0] = a; s[0][1] = b; s[1][0] = c; s[1][1] = d; } mat operator * (const mat& c) { mat ans; memset(ans.s, 0, sizeof(ans.s)); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) ans.s[i][j] = (s[i][0] * c.s[0][j] + s[i][1] * c.s[1][j]); return ans; } mat operator % (int mod) { for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) s[i][j] %= mod; return *this; } mat operator + (const mat& c) { mat ans; memset(ans.s, 0, sizeof(ans.s)); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) ans.s[i][j] = s[i][j] + c.s[i][j]; return ans; } void put() { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) printf("%I64d ", s[i][j]); printf("\n"); } } }c(1, 1, 1, 0), tmp(1, 0, 0, 1); ll k, b, n, M; mat pow_mod(int n, mat c) { if (n == 0) return tmp; if (n == 1) return c; mat a = pow_mod(n / 2, c); mat ans = a * a % M; if (n % 2) ans = ans * c % M; return ans; } mat sum(int n, mat a) { if (n == 1) return a; if (n & 1) return (pow_mod(n, a) + sum(n - 1, a)) % M; else return (((pow_mod(n / 2, a) + tmp) % M) * sum(n / 2, a) % M); } int main() { while (scanf("%I64d%I64d%I64d%I64d", &k, &b, &n, &M) != EOF) { mat A = pow_mod(b, c); mat B = pow_mod(k, c); mat C = sum(n - 1, B) + tmp; C = C * A; printf("%I64d\n", C.s[0][1] % M); } return 0; }
相关文章推荐
- HDU1588-Gauss Fibonacci(矩阵快速幂+等比数列二分求和)
- HDU1588 Gauss Fibonacci (矩阵快速幂+等比数列二分求和)
- HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和)
- HDU - 1588 Gauss Fibonacci (矩阵高速幂+二分求等比数列和)
- HDU 1588 Gauss Fibonacci(矩阵快速幂+二分求等比数列和)
- hdu 1588 Gauss Fibonacci(等比矩阵二分求和)
- POJ 3233 Matrix Power Series (矩阵快速幂+等比数列二分求和)
- hdu1588 Gauss Fibonacci(矩阵快速幂+二分求矩阵等比和)
- hdoj 1588 矩阵快速幂 二分等比数列求和模板
- HDU 1588 Gauss Fibonacci(矩阵快速幂+二分等比序列求和)
- HDU 2254 奥运(矩阵高速幂+二分等比序列求和)
- hdu 1588 Gauss Fibonacci(斐波那契,等比数列求和,矩阵快速幂)
- poj3233 矩阵等比数列求和 二分
- HDU - 1588 Gauss Fibonacci (矩阵快速幂+二分求等比数列和)
- POJ 3233 矩阵运算,等比数列二分求和,矩阵
- 等比数列二分求和(首项为0次项与1次项的方法)
- POJ 3233 Matrix Power Series (矩阵&快速等比数列求和取模)
- Codeforces 327C 乘法逆元 + 费马小定理 || 等比数列二分求和取模
- hdu1588 Gauss Fibonacci (矩阵快速幂)
- HDU 1588-Gauss Fibonacci(矩阵快速幂+二分求矩阵和)