7_22_F题 Recurrences(矩阵快速幂)

来源:互联网 发布:酒店网络设计方案 编辑:程序博客网 时间:2024/06/04 17:52

7_22_F题 Recurrences(矩阵快速幂)


题意

当n > d 时有 f(n)=ni=1aif(ni)
给出n,a1~ad,f[1]~f[n],求 f[n]%mod

思路

很明显的矩阵快速幂,转移矩阵如下

a1100a2010ad1001ad000

然后直接矩阵快速幂就行了。

代码

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn = 16;typedef long long ll;ll mod,d;ll a[maxn];ll f[maxn];struct Mat {    ll maze[maxn][maxn];    Mat(){        memset(maze,0,sizeof maze);    }};int choose;Mat Mat_mul(const Mat& a, const Mat& b){    Mat res;    for(int i = 0; i < d; i++)        for(int j = 0; j < d; j++){            res.maze[i][j] = 0;            for(int k = 0; k < d; k++) {                res.maze[i][j] = (res.maze[i][j] + (a.maze[i][k] * b.maze[k][j])%mod) % mod;            }        }    return res;}Mat Mat_Qpow(int n){    Mat base,res;    for(int i = 0 ; i < maxn ; i ++)        base.maze[0][i] = a[i]%mod;    for(int i = 1 ; i < maxn ; i ++)        base.maze[i][i-1] = 1;    for(int i = 0 ; i < maxn ; i ++)        res.maze[i][i] = 1;    while(n > 0){        if(n & 1) {            res = Mat_mul(res, base);        }        base = Mat_mul(base, base);        n >>= 1;    }    return res;}int main(){    ll n;    while(~scanf("%lld %lld %lld", &d, &n, &mod),mod){        memset(a,0,sizeof a);        for(int i = 0 ; i < d ; i ++)            scanf("%lld",a + i);        for(int i = 0 ; i < d ; i ++)            scanf("%lld",f + i);        auto ans= Mat_Qpow(n-d);        ll sum = 0;        for(int i = 0 ; i < d ; i ++)            sum = (sum + ans.maze[0][i]*f[d-i-1])%mod;        if(n <= d) sum = f[n-1]%mod;        printf("%lld\n", sum);    }    return 0;}
0 0
原创粉丝点击