HDU6470 Count

好久没写矩阵快速幂(其实这题可以直接用杜教的BM板子,比赛时突然想练一下矩阵快速幂)
比较难搞的是 n 3 n^3 n3
考虑 n 3 − > ( n + 1 ) 3 n^3 -> (n+1)^3 n3>(n+1)3,多了 3 n 2 , 3 n , 1 3n^2,3n,1 3n2,3n,1
然后就可以构造一个6x6的矩阵 [ f ( n − 1 ) , f ( n − 2 ) , n 3 , 3 n 2 , 3 n , 1 ] [f(n-1),f(n-2),n^3,3n^2,3n,1] [f(n1),f(n2),n3,3n2,3n,1]
HDU6470 Count_第1张图片

#include 
using namespace std;
#define rep(i,a,n) for (int i=a;i
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=123456789;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}

const int maxn = 6;

int T;
ll n;
struct Matrix{
    ll a[maxn][maxn];
    void init(){    
        memset(a, 0, sizeof(a));
        for(int i=0;i<maxn;++i){
            a[i][i] = 1;
        }
    }
    void Init(){    
        memset(a, 0, sizeof(a));
    }
};

Matrix mul(Matrix a, Matrix b){
    Matrix ans;
    for(int i=0;i<maxn;++i){
        for(int j=0;j<maxn;++j){
            ans.a[i][j] = 0;
            for(int k=0;k<maxn;++k){
                ans.a[i][j] += a.a[i][k] * b.a[k][j];
                ans.a[i][j] %= mod; 
            }
        }
    } 
    return ans;
}

Matrix qpow(Matrix a, ll n){
    Matrix ans;
    ans.init();
    while(n){
        if(n&1) ans = mul(ans, a);
        a = mul(a, a);
        n /= 2;
    } 
    return ans;
}

void output(Matrix a){
    for(int i=0;i<maxn;++i){
        for(int j=0;j<maxn;++j){
            cout << a.a[i][j] << " ";
        }
        cout << endl;
    }
}


int main(int argc, char const *argv[])
{
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    Matrix tmp;
    tmp.Init();
    tmp.a[0][0] = 1;
    tmp.a[0][1] = 1; 
    tmp.a[1][0] = 2;
    tmp.a[2][0] = 1;
    tmp.a[2][2] = 1;
    tmp.a[3][2] = 1;
    tmp.a[3][3] = 1;
    tmp.a[4][2] = 1;
    tmp.a[4][3] = 2;
    tmp.a[4][4] = 1;
    tmp.a[5][2] = 1;
    tmp.a[5][3] = 3;
    tmp.a[5][4] = 3;
    tmp.a[5][5] = 1;
    cin >> T;
    while(T--)
    {
        cin >> n;
        Matrix t = qpow(tmp,n-2);
        //output(t);
        Matrix ans;
        ans.Init();
        ans.a[0][0] = 2;
        ans.a[0][1] = 1;
        ans.a[0][2] = 3*3*3;
        ans.a[0][3] = 3*3*3;
        ans.a[0][4] = 3*3;
        ans.a[0][5] = 1;
        Matrix as = mul(ans,t);
        cout << as.a[0][0] << endl;
    }
    return 0;
}

你可能感兴趣的:(acm,数学)