UVA 10870 - Recurrences 矩阵快速幂
2016-01-20 23:44
309 查看
[b] Recurrences[/b]
Consider recurrent functions of the following form:
f(n) = a1f(n − 1) + a2f(n − 2) + a3f(n − 3) + . . . + adf(n − d), for n > d,
where a1, a2, . . . , ad are arbitrary constants.
A famous example is the Fibonacci sequence, defined as: f(1) = 1, f(2) = 1, f(n) = f(n − 1) +
f(n − 2). Here d = 2, a1 = 1, a2 = 1.
Every such function is completely described by specifying d (which is called the order of recurrence),
values of d coefficients: a1, a2, . . . , ad, and values of f(1), f(2), . . . , f(d). You’ll be given these numbers,
and two integers n and m. Your program’s job is to compute f(n) modulo m.
[b]Input[/b]
Input file contains several test cases. Each test case begins with three integers: d, n, m, followed by
two sets of d non-negative integers. The first set contains coefficients: a1, a2, . . . , ad. The second set
gives values of f(1), f(2), . . . , f(d).
You can assume that: 1 ≤ d ≤ 15, 1 ≤ n ≤ 2
31 − 1, 1 ≤ m ≤ 46340. All numbers in the input will
fit in signed 32-bit integer.
Input is terminated by line containing three zeroes instead of d, n, m. Two consecutive test cases
are separated by a blank line.
[b]Output[/b]
For each test case, print the value of f(n)( mod m) on a separate line. It must be a non-negative integer,
less than m.
[b]Sample Input[/b]
1 1 100
2
1
2 10 100
1 1
1 1
3 2147483647 12345
12345678 0 12345
1 2 3
0 0 0
[b]Sample Output[/b]
1
55
423
[b]题意:[/b]
给你 :递推关系f(n)=a1*f(n-1) + a2*f(n-2) + .. ad*f(n-d),计算f(n)%m
[b]题解:[/b]
n太大,所以矩阵快速幂咯
Consider recurrent functions of the following form:
f(n) = a1f(n − 1) + a2f(n − 2) + a3f(n − 3) + . . . + adf(n − d), for n > d,
where a1, a2, . . . , ad are arbitrary constants.
A famous example is the Fibonacci sequence, defined as: f(1) = 1, f(2) = 1, f(n) = f(n − 1) +
f(n − 2). Here d = 2, a1 = 1, a2 = 1.
Every such function is completely described by specifying d (which is called the order of recurrence),
values of d coefficients: a1, a2, . . . , ad, and values of f(1), f(2), . . . , f(d). You’ll be given these numbers,
and two integers n and m. Your program’s job is to compute f(n) modulo m.
[b]Input[/b]
Input file contains several test cases. Each test case begins with three integers: d, n, m, followed by
two sets of d non-negative integers. The first set contains coefficients: a1, a2, . . . , ad. The second set
gives values of f(1), f(2), . . . , f(d).
You can assume that: 1 ≤ d ≤ 15, 1 ≤ n ≤ 2
31 − 1, 1 ≤ m ≤ 46340. All numbers in the input will
fit in signed 32-bit integer.
Input is terminated by line containing three zeroes instead of d, n, m. Two consecutive test cases
are separated by a blank line.
[b]Output[/b]
For each test case, print the value of f(n)( mod m) on a separate line. It must be a non-negative integer,
less than m.
[b]Sample Input[/b]
1 1 100
2
1
2 10 100
1 1
1 1
3 2147483647 12345
12345678 0 12345
1 2 3
0 0 0
[b]Sample Output[/b]
1
55
423
[b]题意:[/b]
给你 :递推关系f(n)=a1*f(n-1) + a2*f(n-2) + .. ad*f(n-d),计算f(n)%m
[b]题解:[/b]
n太大,所以矩阵快速幂咯
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std ; typedef long long ll; const int N = 50; ll m,d,f ; struct Matrix { ll mat[20][20]; }; Matrix multi (Matrix a, Matrix b) { Matrix ans; memset(ans.mat,0,sizeof(ans.mat)); for(int i = 1; i <= d; i++) { for(int j = 1; j <= d; j++) { for(int k = 1; k <= d; k++) ans.mat[i][j] += a.mat[i][k] * b.mat[k][j],ans.mat[i][j] %= m; } } return ans; } ll powss(ll n,Matrix ans) { Matrix p,t;memset(t.mat,0,sizeof(t.mat)); for(int i = 1; i <= d; i++) t.mat[i][i] = 1; while(n) { if(n&1) t = multi(t,ans); n>>=1; ans = multi(ans,ans); } ll tmp=0; for(int i=1;i<=d;i++) tmp=(tmp+t.mat[1][i]*f[d - i + 1])%m; return tmp; } int main() { ll n,a ; while(~scanf("%lld%lld%lld",&d,&n,&m)) { if(d == 0 && m == 0 &&n == 0) break; for(int i = 1; i <= d; i++) scanf("%lld",&a[i]); for(int i = 1; i <= d; i++) scanf("%lld",&f[i]); if(n <= d) {cout<<f <<endl;continue;} Matrix ans;memset(ans.mat,0,sizeof(ans.mat)); for(int i = 1; i <= d; i++) ans.mat[i][i-1] = 1; for(int i = 1; i <= d; i++) ans.mat[1][i] = a[i]; printf("%lld\n",powss(n - d,ans)); } return 0; }
相关文章推荐
- Linux tar 命令
- 第五天,uiscorllview的滚动和缩放,以及代理调用,定时器,对话框
- 【MongoDB】 Windows 安装
- WSAStartup
- 初探JSP
- Gradle DSL method not found: 'android()
- 射频通信原理
- (转)VS2010结合水晶报表做条码标签打印功能
- 关于apache代理报错error reading status line from remote server
- Java的进程内缓存框架:EhCache (转)
- SQL TRACE
- UVA 822 Queue and A
- Uncowed Forces
- chapter16:例行性工作(crontab)之二:循环执行的例行性工作调度
- iOS开发 masonry 设置tableHeadView
- WSADATA
- 有线网速正常,无线网速不正常引发的一场“战役”
- <s:select />标签的用法
- HIVE表保存的路径
- G面经prepare: Maximum Subsequence in Another String's Order