矩阵——hdu3306 Another kind of Fibonacci

来源:互联网 发布:mac 查看所有进程 编辑:程序博客网 时间:2024/05/17 15:19

http://acm.hdu.edu.cn/showproblem.php?pid=3306
别人的博客写的实在是太好了,我都不好意思不转了
http://www.cnblogs.com/zzuli2sjy/p/5929026.html
这里写图片描述
然后zzh说这道题会卡常;
然后我各种优化加了之后109ms进第一面了;

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define Ll long longusing namespace std;struct jv{    int n,m;    int a[5][5];    jv(){n=m=0;memset(a,0,sizeof a);}}a,ans;int n,x,y,mo=10007;void make(Ll x,Ll y){    a.n=a.m=4;    memset(a.a,0,sizeof a.a);    a.a[1][1]=a.a[3][2]=1;    a.a[1][2]=a.a[2][2]=x*x%mo;    a.a[1][3]=a.a[2][3]=y*y%mo;    a.a[1][4]=a.a[2][4]=x*y*2%mo;    a.a[4][2]=x;a.a[4][4]=y;    ans.m=1; ans.n=4;    memset(ans.a,0,sizeof ans.a);    ans.a[1][1]=2;    ans.a[2][1]=1;    ans.a[3][1]=1;    ans.a[4][1]=1;}jv cheng(jv a,jv b){    jv c; c.n=a.n; c.m=b.m;    for(int i=1;i<=c.n;i++)        for(int k=1;k<=a.m;k++)if(a.a[i][k])            for(int j=1;j<=c.m;j++)                c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%mo;    return c;}jv ksm(int k){    jv ans=a,c=a;    k--;    while(k){        if(k&1)ans=cheng(ans,c);        k>>=1; c=cheng(c,c);    }    return ans;}int main(){    while(scanf("%d%d%d",&n,&x,&y)!=-1){        n++; x%=mo; y%=mo;        if(n==1){printf("1\n");continue;}        if(n==2){printf("2\n");continue;}        make(x,y);        printf("%d\n",cheng(ksm(n-2),ans).a[1][1]);    }}
1 0