HDU6470 Count(矩阵快速幂)
Problem Description
Farmer John有n头奶牛.
某天奶牛想要数一数有多少头奶牛,以一种特殊的方式:
第一头奶牛为1号,第二头奶牛为2号,第三头奶牛之后,假如当前奶牛是第n头,那么他的编号就是2倍的第n-2头奶牛的编号加上第n-1头奶牛的编号再加上自己当前的n的三次方为自己的编号.
现在Farmer John想知道,第n头奶牛的编号是多少,估计答案会很大,你只要输出答案对于123456789取模.
Input
第一行输入一个T,表示有T组样例
接下来T行,每行有一个正整数n,表示有n头奶牛 (n>=3)
其中,T=10^4,n<=10^18
Output
共T行,每行一个正整数表示所求的答案
Sample Input
5 3 6 9 12 15
Sample Output
31 700 7486 64651 527023
这道题我们在最开始做的时候用Java一边做一边模,但模的数为123456789,如果n为123456788,n的三次方肯定要爆,所以要把n的三次方解决,考虑n3变成(n+1)的三次方
,多了3*n的2次方,3n,1
然后就可以构造一个6x6的矩阵[f(n−1),f(n−2),n的三次方,3*n的2次方,3n,1]
解题代码:
#include <bits/stdc++.h> using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define pb push_back #define mpmake_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 longll; typedef pair<int,int> PII; const ll mod=123456789; llpowmod(lla,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; } llgcd(lla,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); 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; }