您的位置:首页 > 大数据 > 人工智能

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

2017-08-25 10:21 537 查看
传送门

Array Challenge

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


[align=left]Problem Description[/align] There’s an array that is generated by following rule.
h0=2,h1=3,h2=6,hn=4hn−1+17hn−2−12hn−3−16
And let us define two arrays bnandan as below.
bn=3hn+1hn+9hn+1hn−1+9h2n+27hnhn−1−18hn+1−126hn−81hn−1+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.

[align=left]Input[/align] 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.

[align=left]Output[/align] For each test case print ⌊√(an)⌋modular 1000000007.
[align=left]Sample Input[/align]
3

4

7

9

[align=left]Sample Output[/align]
1255

324725

13185773


题目大意:

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

解题思路:

打表,打出⌊√(an)⌋ 的前几项,然后发现一个规律,跟 hn 的生成方式是差不多的,然后就能写出一个递推式。令fn=⌊√(an)⌋

fn=4fn−1+17fn−2−12fn−3

构造矩阵为:

417−12100010

然后矩阵快速幂计算就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
**/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐