hdu 6172 矩阵快速幂 找规律

来源:互联网 发布:张伯礼 知乎 编辑:程序博客网 时间:2024/05/21 21:49

Array Challenge

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


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 &#8970;√(a_n )&#8971; modular 1000000007.
 

Sample Input
3479
 

Sample Output
125532472513185773
 

Source
2017 Multi-University Training Contest - Team 10


题意:

anmod(1e9+7)


题解:

fn=an,写出前几项f2=31,f3=197,f4=1255,f5=7997,f6=50959
h3=35,h4=190,h5=1267,h6=7862
可以发现fnhn的递推结果很像,
于是根据hn的递推关系猜测fn=4fn1+17fn212fn3
是一个线性递推式,用矩阵快速幂



计算an这个数组前几个数字的代码:

然后就可以发现规律了

#include<math.h>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define LL long longLL k;struct Matrix{    int m[10][10];};Matrix unit,init;void Init(){    memset(init.m,0,sizeof(init.m));    init.m[1][0]=1;    init.m[2][1]=1;    init.m[3][3]=1;    init.m[0][0]=4;    init.m[0][1]=17;    init.m[0][2]=-12;    init.m[0][3]=-16;    memset(unit.m,0,sizeof(unit.m));    for(int i=0;i<4;i++)        unit.m[i][i]=1;}Matrix Mul(Matrix a,Matrix b){    Matrix c;    for(int i=0;i<4;i++)        for(int j=0;j<4;j++){            c.m[i][j]=0;            for(int k=0;k<4;k++)                c.m[i][j]+=(a.m[i][k]*b.m[k][j]);        }    return c;}Matrix Pow(Matrix a,Matrix b,int x){    while(x)    {        if(x&1)            b=Mul(a,b);        a=Mul(a,a);        x>>=1;    }    return b;}LL fast_pow(LL a,LL b){    LL ans=1;    while(b)    {        if(b&1) ans*=a;        a*=a;        b>>=1;    }    return ans;}int main(){    LL n;    int a[10]={6,3,2,1};    freopen("in.txt","r",stdin);    while(scanf("%lld",&n)!=EOF)    {        Init();        Matrix res=Pow(init,unit,n-2);        LL ans=0,h3=0,h2=0,h1=0;        for(int i=0;i<4;i++)            h3+=res.m[0][i]*a[i];        for(int i=0;i<4;i++)            h2+=res.m[1][i]*a[i];        for(int i=0;i<4;i++)            h1+=res.m[2][i]*a[i];        ans=3*h3*h2+9*h3*h1+9*h2*h2+27*h2*h1;        ans=ans-18*h3-126*h2-81*h1+192;        ans+=fast_pow(4,n-1);        LL x=((LL)sqrt(ans*1.0));        printf("%8lld   %8lld  %8lld\n",x,h3,h3-x);    }    return 0;}




ac代码,注意精度


#include<math.h>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define LL long long#define mod 1000000007LL k;struct Matrix{    LL m[10][10];};Matrix unit,init;void Init(){    memset(init.m,0,sizeof(init.m));    init.m[1][0]=1;    init.m[2][1]=1;    init.m[0][0]=4;    init.m[0][1]=17;    init.m[0][2]=-12;    memset(unit.m,0,sizeof(unit.m));    for(int i=0;i<3;i++)        unit.m[i][i]=1;}Matrix Mul(Matrix a,Matrix b){    Matrix c;    for(int i=0;i<3;i++)        for(int j=0;j<3;j++){            c.m[i][j]=0;            for(int k=0;k<3;k++)                c.m[i][j]=(c.m[i][j]+(a.m[i][k]*b.m[k][j])%mod+mod)%mod;        }    return c;}Matrix Pow(Matrix a,Matrix b,LL x){    while(x)    {        if(x&1)            b=Mul(a,b);        a=Mul(a,a);        x>>=1;    }    return b;}int main(){    LL n,T;    int a[10]={1255,197,31};    freopen("in.txt","r",stdin);    scanf("%lld",&T);    while(T--)    {        scanf("%lld",&n);        if(n==2)       puts("31");        else if(n==3)  puts("197");        else if(n==4)  puts("1255");        else{            Init();            Matrix res=Pow(init,unit,n-4);            LL h=(res.m[0][0]*1255%mod+res.m[0][1]*197%mod+res.m[0][2]*31%mod+mod)%mod;            printf("%lld\n",h);        }    }    return 0;}


阅读全文
0 0
原创粉丝点击