zoukankan      html  css  js  c++  java
  • UVA 10870

                                          Recurrences

    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.
    Input
    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.
    Output
    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.
    Sample Input
    1 1 100
    2
    1
    2 10 100
    1 1
    1 1
    3 2147483647 12345
    12345678 0 12345
    1 2 3
    0 0 0
    Sample Output
    1
    55
    423

    题意:

    给你 :递推关系f(n)=a1*f(n-1) + a2*f(n-2) + .. ad*f(n-d),计算f(n)%m

    题解:

    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[N];
    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[N];
        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[n]<<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
    ",powss(n - d,ans));
        }
        return 0;
    }
  • 相关阅读:
    汇编笔记
    【BZOJ 1701】Cow School(斜率优化/动态凸包/分治优化)
    MS-DOS 6.22 +Vim+masm 汇编环境
    「NOIP2017」时间复杂度
    CCF 201809-3 元素选择器
    CCF 201712-3 Crontab
    ICPC NWERC2019~2020 Practice Contest
    蓝桥杯模拟赛3 F:等差等比有联系 公差公比求通项
    CCF 201509-3 模板生成系统
    CCF 201503-3 节日
  • 原文地址:https://www.cnblogs.com/zxhl/p/5146975.html
Copyright © 2011-2022 走看看