Recurrence UVA10870

来源:互联网 发布:ipad怎么刷windows系统 编辑:程序博客网 时间:2024/06/05 18:19








#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <queue>#include <algorithm>#include <vector>#include <cstring>#include <stack>#include <cctype>#include <utility>   #include <map>#include <string>  #include <climits> #include <set>#include <string>    #include <sstream>#include <utility>   #include <ctime>using std::priority_queue;using std::vector;using std::swap;using std::stack;using std::sort;using std::max;using std::min;using std::pair;using std::map;using std::string;using std::cin;using std::cout;using std::set;using std::queue;using std::string;using std::istringstream;using std::make_pair;using std::getline;using std::greater;using std::endl;typedef long long LL;const int MAXN(20);int MOD;struct MAT{int r, c;LL arr[MAXN][MAXN];MAT(int tr, int tc): r(tr), c(tc){memset(arr, 0, sizeof(arr[0])*r);}MAT(){}};void mat_mult(const MAT &op1,const MAT &op2, MAT &re){re.r = op1.r;re.c = op2.c;memset(re.arr, 0, sizeof(re.arr[0])*re.r);for(int i = 0; i < op1.c; ++i)for(int j = 0; j < op1.r; ++j)for(int k = 0; k < op2.c; ++k)re.arr[j][k]= (re.arr[j][k]+op1.arr[j][i]*op2.arr[i][k])%MOD;}void mat_pow(const MAT &op, MAT &re, int n){MAT t1, t2;t1 = op;memset(re.arr, 0, sizeof(re.arr[0])*re.r);for(int i = 0; i < re.r; ++i)re.arr[i][i] = 1;for(int i = 0; (1LL << i) <= n; ++i){if(n&(1 << i)){t2 = re;mat_mult(t1, t2, re);}mat_mult(t1, t1, t2);t1 = t2;}}int main(){int N, n, i;while(scanf("%d%d%d", &N, &n, &MOD), N+n+MOD){MAT m1(N, N), m2(N, 1), re(N, N);for(i = N-1; i >= 0; --i){scanf("%lld", m1.arr[N-1]+i);}for(i = 0; i < N-1; ++i)m1.arr[i][i+1] = 1LL;for(i = 0; i < N; ++i){scanf("%lld", m2.arr[i]);m2.arr[i][0] %= MOD;}if(n <= N)printf("%lld\n", m2.arr[n-1][0]);else{mat_pow(m1, re, n-N);mat_mult(re,  m2, m1);printf("%lld\n", m1.arr[N-1][0]);}}return 0;}




原创粉丝点击