HDU 6172 Array Challenge(打表+矩阵快速幂)——2017 Multi-University Training Contest

来源:互联网 发布:软件汉化工具 编辑:程序博客网 时间:2024/05/29 04:15

传送门

Array Challenge

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 153428/153428 K (Java/Others)
Total Submission(s): 203    Accepted Submission(s): 91


Problem Description
There’s an array that is generated by following rule.
h0=2,h1=3,h2=6,hn=4hn1+17hn212hn316
And let us define two arrays bnandan as below.
bn=3hn+1hn+9hn+1hn1+9h2n+27hnhn118hn+1126hn81hn1+192(n>0)
an=bn+4n
Now, you have to print (an) , n>1.
Your answer could be very large so print the answer modular 1000000007.
 

Input
The first line of input contains T (1 <= T <= 1000) , the number of test cases.
Each test case contains one integer n (1 < n <= 1015) in one line.
 

Output
For each test case print (an)modular 1000000007.
 

Sample Input
3
4
7
9
 

Sample Output
1255
324725
13185773

题目大意:

给定 hn,bn,an 的生成方式,求 (an)mod1e9+7

解题思路:

打表,打出(an) 的前几项,然后发现一个规律,跟 hn 的生成方式是差不多的,然后就能写出一个递推式。令fn=(an)
fn=4fn1+17fn212fn3
构造矩阵为:

41712100010

然后矩阵快速幂计算就OK了。
代码:

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int MAXN = 3;const double PI = acos(-1);const double eps = 1e-8;const LL MOD = 1e9+7;inline int GCD(int a, int b){    if(b  == 0) return a;    return GCD(b, a%b);}inline LL GCD(LL a, LL b){    if(b  == 0) return a;    return GCD(b, a%b);}inline int LCM(int a, int b){    return a/GCD(b, a%b)*b;}inline LL LCM(LL a, LL b){    return a/GCD(b, a%b)*b;}namespace IO {    const int MX = 4e7; //1e7占用内存11000kb    char buf[MX]; int c, sz;    void begin() {        c = 0;        sz = fread(buf, 1, MX, stdin);    }    inline bool read(int &t) {        while(c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) c++;        if(c >= sz) return false;        bool flag = 0; if(buf[c] == '-') flag = 1, c++;        for(t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; c++) t = t * 10 + buf[c] - '0';        if(flag) t = -t;        return true;    }}struct Matrix{    LL mat[MAXN][MAXN];};Matrix Multi(Matrix A, Matrix B){    Matrix C;    for(int i=0; i<MAXN; i++){        for(int j=0; j<MAXN; j++){            C.mat[i][j] = 0;            for(int k=0; k<MAXN; k++){                C.mat[i][j] = (C.mat[i][j]+A.mat[i][k]*B.mat[k][j]%MOD)%MOD;            }        }    }    return C;}Matrix Pow(Matrix A, LL b){    Matrix ans;    memset(ans.mat, 0, sizeof(ans.mat));    for(int i=0; i<MAXN; i++) ans.mat[i][i] = 1;    while(b){        if(b & 1) ans = Multi(ans, A);        b>>=1;        A = Multi(A, A);    }    return ans;}int main(){    //freopen("C:/Users/yaonie/Desktop/in.txt", "r", stdin);    //freopen("C:/Users/yaonie/Desktop/out.txt", "w", stdout);    int T; scanf("%d", &T);    while(T--){        LL n; scanf("%lld",&n);        if(n == 2) puts("31");        else if(n == 3) puts("197");        else if(n == 4) puts("1255");        else{            Matrix tmp;            tmp.mat[0][0]=4, tmp.mat[0][1]=1, tmp.mat[0][2]=0;            tmp.mat[1][0]=17, tmp.mat[1][1]=0, tmp.mat[1][2]=1;            tmp.mat[2][0]=-12, tmp.mat[2][1]=0, tmp.mat[2][2]=0;            tmp = Pow(tmp, n-4);            LL ans = 1255*tmp.mat[0][0]+197*tmp.mat[1][0]+31*tmp.mat[2][0];            ans = (ans%MOD+MOD)%MOD;            cout<<ans<<endl;        }    }    return 0;}/**                   _ooOoo_                  o8888888o                  88" . "88                  (| -_- |)                  O\  =  /O               ____/`---'\____             .'  \\|     |//  `.            /  \\|||  :  |||//  \           /  _||||| -:- |||||-  \           |   | \\\  -  /// |   |           | \_|  ''\---/''  |   |           \  .-\__  `-`  ___/-. /         ___`. .'  /--.--\  `. . __      ."" '<  `.___\_<|>_/___.'  >'"".     | | :  `- \`.;`\ _ /`;.`/ - ` : | |     \  \ `-.   \_ __\ /__ _/   .-` /  /======`-.____`-.___\_____/___.-`____.-'======                   `=---='^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^         佛祖保佑       每次AC**/
阅读全文
0 0
原创粉丝点击