vijos 1067 Warcraft III 守望者的烦恼 矩阵

题目链接

 

我们可以很容易的推出dp的式子, dp[i] = sigma(j : 1 to k) dp[i-j]。

但是n太大了, 没有办法直接算, 所以我们构造一个矩阵, 然后快速幂就好了。

就像这样构建矩阵(举个例子

#include <vector>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 7777777;
const int inf = 1061109567;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
ll n, m, dp[11];
struct Matrix
{
    ll a[102][102];
    Matrix() {
        mem(a);
    }
};
Matrix operator * (Matrix a, Matrix b) {
    Matrix c;
    for(int i = 0; i<n; i++) {
        for(int j = 0; j<n; j++) {
            for(int k = 0; k<n; k++) {
                c.a[i][j] += a.a[i][k]*b.a[k][j];
                c.a[i][j] %= mod;
            }
        }
    }
    return c;
}
Matrix operator ^(Matrix a, ll b) {
    Matrix tmp;
    for(int i = 0; i<n; i++)
        tmp.a[i][i] = 1;
    while(b) {
        if(b&1)
            tmp = tmp*a;
        a = a*a;
        b>>=1;
    }
    return tmp;
}
int main()
{
    ll k;
    cin>>n>>k;
    dp[0] = 1;
    for(int i = 1; i<=n; i++) {
        for(int j = 0; j<i; j++)
            dp[i] += dp[j];
    }
    if(k<=n) {
        cout<<dp[k]<<endl;
        return 0;
    }
    Matrix tmp, ans;
    for(int i = 0; i<n; i++) {
        tmp.a[0][i] = 1;
        tmp.a[i+1][i] = 1;
    }
    tmp = tmp^(k-n);
    for(int i = 0; i<n; i++) {
        ans.a[n-i-1][0] = dp[i+1];
    }
    ans = tmp*ans;
    cout<<ans.a[0][0]<<endl;
    return 0;
}

 

posted on 2016-03-12 13:26  yohaha  阅读(411)  评论(0编辑  收藏  举报

导航