uva 12045 (矩阵快速幂)
来源:互联网 发布:erp系统java项目 编辑:程序博客网 时间:2024/06/05 17:29
题意:
一个长度为正数的字符串,只包含“a"和"b"两种字符。
每次操作,把所有的b变成ab,a变成b。
如S(1) = ab, 则S(2)=b(ab) =bab
记L(n)为第n个串的长度。
给出L(n) = X , L(m) = Y, L(k)
做法:
设S(n)中字符a、b的个数分别为a(n)、b(n),则L(n)= a(n) + b(n)
很明显有 a(n+1)=b(n),b(n+1) = a(n)+b(n)
即满足斐波那契数列的性质。
于是可以通过构造转移矩阵,利用快速幂,来得到任意两项之间的关系。
不妨设n < m,假设得到的矩阵为
|a b|
|c d|
则有 a * a(n) + b * b(n) = a(m)
c * a(n) + d * b(n) = b(m)
又
a(n) + b(n) = L(n) = X
a(m) + b(m) = L(m) = Y
于是可解出a(n), b(n) ,若小于0 说明字符个数小于0,明显不合题意。
类似可算出a(1),b(1),同样必须保证大于等于0
最后再推出k的情况即可。
#include <cstdio>#include <iostream>using namespace std;const int MOD = 1000000007, INF = 1e9;typedef long long ll;const int N = 2;struct Mat { ll mat[N][N]; void init() { for(int i = 0; i < N; i++) for(int j = 0; j < N; j++) mat[i][j] = i || j ? 1 : 0; } void init2(int x) { for(int i = 0; i < N; i++) for(int j = 0; j < N; j++) mat[i][j] = i == j ? x : 0; } Mat operator * (const Mat &ano) { Mat res; res.init2(0); for(int i = 0; i < N; i++) for(int j = 0; j < N; j++) for(int k = 0; k < N; k++) { res.mat[i][j] += mat[i][k] * ano.mat[k][j]; res.mat[i][j] %= MOD; } return res; }};Mat quickPow(Mat A, int n) { Mat res; res.init2(1); while(n) { if(n & 1) res = res * A; A = A * A; n >>= 1; } return res;}// a * x + b * y = s1// c * x + d * y = s2void fun(ll a, ll b, ll s1, ll c, ll d, ll s2, ll &x, ll &y) { x = y = -1; if(b * c != d * a) { y = (a * s2 - c * s1) / (a * d - b * c); if(a) x = (s1 - b * y) / a; else if(c) x = (s2 - d * y) / c; if(a * x + b * y != s1 || c * x + d * y != s2) x = y = -1; }}int main() {// freopen("in.txt", "r", stdin); int t, n, x, m, y, k; ll ans; Mat A; scanf("%d", &t); while(t--) { scanf("%d%d%d%d%d", &n, &x, &m, &y, &k); if(n > m) { swap(n, m); swap(x, y); } ll an, bn; A.init(); A = quickPow(A, m - n); fun(1, 1, x, A.mat[0][0] + A.mat[1][0], A.mat[0][1] + A.mat[1][1], y, an, bn); if(an < 0 || bn < 0) { puts("Impossible"); continue; } ll a1, b1; A.init(); A = quickPow(A, n-1); fun(A.mat[0][0], A.mat[0][1], an, A.mat[1][0], A.mat[1][1], bn, a1, b1); if(a1 < 0 || b1 < 0){ puts("Impossible"); continue; } A.init(); ll ak, bk; if(k >= n) { A = quickPow(A, k - n); ak = an * ((A.mat[0][0] + A.mat[1][0]) % MOD); bk = bn * ((A.mat[0][1] + A.mat[1][1]) % MOD); ak %= MOD, bk %= MOD; ans = ak + bk; } else { A = quickPow(A, n - k); fun(A.mat[0][0], A.mat[0][1], an, A.mat[1][0], A.mat[1][1], bn, ak, bk); if(ak < 0 || bk < 0) { puts("Impossible"); continue; } ak %= MOD, bk %= MOD; ans = ak + bk; } ans %= MOD; printf("%d\n", (int)ans); } return 0;}
0 0
- uva 12045 (矩阵快速幂)
- UVA 10870 (矩阵快速幂)
- uva 10870 Recurrences(矩阵快速幂)
- UVA - 10870 Recurrences (矩阵快速幂)
- UVA 10870 Recurrences(矩阵快速幂)
- UVa 10870 - Recurrences (矩阵构造 矩阵快速幂)
- uva 10870(矩阵快速幂)
- uva 12470(矩阵快速幂)
- uva 10698 矩阵快速幂
- 【矩阵快速幂】Recurrences UVA
- UVA 11551(矩阵快速幂)
- UVA 10689 矩阵快速幂 + 快速幂取模
- uva 10229 (fib矩阵形式+矩阵快速幂)uva 10518 (fib(n)调用多少次)
- uva 10655 Algebraic Problem(矩阵快速幂)
- uva 10229 - Modular Fibonacci(矩阵快速幂)
- uva 10518 - How Many Calls?(矩阵快速幂)
- Uva 10870 Recurrences 解题报告(矩阵快速幂)
- uva 10870 Recurrences(数学:矩阵快速幂)
- linux centos6.5 安装网卡驱动程序
- linux centos6.5 利用yum和configure安装R语言
- 网络体系结构:网络分层
- 为什么Android手机总是越用越慢?
- report on "user interface design". on Oct 10th
- uva 12045 (矩阵快速幂)
- 血眼龙王传--秋叶青篇
- 表单兼容类型设计
- PKU 2226 - Muddy Fields (最小点覆盖)
- map+pair Bayan 2015 Contest Warm Up D题
- Spring MVC 文件下载最佳实践
- C# 6.0 (C# vNext) 新功能之:Auto-Properties with Initializers
- windows桌面显示“系统文件夹”和“系统图标”
- DirectX11 学习笔记8 - 最简单的光照