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

2017 Multi-University Training Contest 10 1002 Array Challenge HDU 6172(找规律 矩阵快速幂)

2017-08-24 21:56 483 查看
题意: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.

思路:这规律都能找到。。。也是厉害的。。。

摘自博客:点击打开链接

解题思路:设fn=⌊an−−√⌋,写出前几项f2=31,f3=197,f4=1255,f5=7997,f6=50959 
又h3=35,h4=190,h5=1267,h6=7862 
可以发现fn跟hn的递推结果很像, 
于是根据hn的递推关系猜测fn=4fn−1+17fn−2−12fn−3 
是一个线性递推式,用矩阵快速幂。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
struct node
{
ll s[5][5];
};

node mul(node a, node b)
{
node t;
memset(t.s, 0, sizeof(t.s));
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++)
for(int k = 1; k <= 3; k++)
t.s[i][j] = (t.s[i][j]+a.s[i][k]*b.s[k][j]+mod)%mod;
return t;
}

node mt_pow(node p, ll q)
{
node res;
memset(res.s, 0, sizeof(res.s));
for(int i = 1; i <= 3; i++) res.s[i][i] = 1;
while(q)
{
if(q%2) res = mul(res, p);
p = mul(p, p);
q /= 2;
}
return res;
}

int main(void)
{
int t;
cin >> 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 if(n == 5) puts("7997");
else
{
node base;
memset(base.s, 0, sizeof(base.s));
base.s[1][1] = 4, base.s[1][2] = 17, base.s[1][3] = -12;
base.s[2][1] = 1, base.s[3][2] = 1;
node ans = mt_pow(base, n-4);
ll res = (ans.s[1][1]*1255%mod+ans.s[1][2]*197%mod+ans.s[1][3]*31%mod+mod)%mod;
printf("%lld\n", res);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HDU 多校 矩阵快速幂
相关文章推荐