码迷,mamicode.com
首页 > 其他好文 > 详细

uva10870 矩阵

时间:2016-04-27 20:51:20      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:

f(n) = a1f(n − 1) + a2f(n − 2) + a3f(n − 3) + . . . + adf(n − d), for n > d,

可以用矩阵进行优化,直接构造矩阵,然后快速幂即可。

#include<map>
#include<set>
#include<string>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<time.h>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 1000000001
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int MAXN = 20;
struct Mat
{
    ll a[MAXN][MAXN];
    void Init(){
        memset(a,0,sizeof(a));
        for(int i = 0; i < 20; i++){
            a[i][i] = 1;
        }
    }
};
ll fa[MAXN],d[MAXN];
ll n,k,MOD;
Mat a;
void Init()
{
    memset(a.a,0,sizeof(a.a));
    for(int i = 0; i < n-1; i++){
        a.a[i][i+1] = 1;
    }
    for(int i = 0; i < n; i++){
        a.a[n-1][i] = fa[n - i - 1];
    }
}
Mat Matadd(Mat a,Mat b)
{
    Mat c;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            c.a[i][j] = (a.a[i][j] + b.a[i][j])%MOD;
        }
    }
    return c;
}
Mat Matmul(Mat a,Mat b)
{
    Mat c;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            c.a[i][j] = 0;
            for(int k = 0; k < n; k++){
                c.a[i][j] += (a.a[i][k] * b.a[k][j])%MOD;
            }
            c.a[i][j] %= MOD;
        }
    }
    return c;
}
Mat power(Mat a,ll n)
{
    Mat c;
    c.Init();
    while(n){
        if(n & 1){
            c = Matmul(c,a);
        }
        a = Matmul(a,a);
        n >>= 1;
    }
    return c;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("data","r",stdin);
    #endif
    while(~scanf("%lld%lld%lld",&n,&k,&MOD)){
        if(!n && !k && !MOD)break;
        for(int i = 0; i < n; i++){
            scanf("%lld",&fa[i]);
            fa[i] %= MOD;
        }
        for(int i = 0; i < n; i++){
            scanf("%lld",&d[i]);
            d[i] %= MOD;
        }
        Init();

        a = power(a,k-1);
        ll ans = 0;
        for(int i = 0; i < n; i++){
            ans += a.a[0][i] * d[i] % MOD;
            ans %= MOD;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

uva10870 矩阵

标签:

原文地址:http://www.cnblogs.com/sweat123/p/5440183.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!