FZU1683---纪念SlingShot(矩阵快速幂(数据劣质))

来源:互联网 发布:网王之数据大师 编辑:程序博客网 时间:2024/06/08 11:41

【题目来源】:https://vjudge.net/problem/FZU-1683
【题意】
题意就像题面描述。
【思路】
这道题和我上一道题Arc of Dream非常相似,并且我在那篇博客里也写的非常详细,所以这里就直接写怎么推导:
设前n项和:S
那么:S[i]=S[i-1]+F[i]
接着:F[i]=3*F[i-1]+2*F[i-2]+7*F[i-3]
代入:S[i]=S[i-1]+3*F[i-1]+2*F[i-2]+7*F[i-3]。
写出系数矩阵:
1 3 2 7
0 3 2 7
0 1 0 0
0 0 1 0
然后,必须强调的一点就是,这道题的数据不符合题意范围:
明明是n>=3,却依旧存在n<3的情况。。。
【代码】

#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>#define LL long longusing namespace std;const LL mod=2009;struct mat{    LL a[5][5];};mat operator*(mat &s,mat &t){    mat r;    memset(r.a,0,sizeof(r.a));    for(int i=1; i<=4; i++)    {        for(int j=1; j<=4; j++)        {            for(int k=1; k<=4; k++)            {                r.a[i][j]+=s.a[i][k]*t.a[k][j];                if(r.a[i][j]>=mod)                    r.a[i][j]%=mod;            }        }    }    return r;}LL pow_mat(mat base,LL k){    mat ans;    for(int i=1; i<=4; i++)        for(int j=1; j<=4; j++)            ans.a[i][j]=(i==j);    while(k)    {        if(k&1)        {            ans=ans*base;        }        base=base*base;        k>>=1;    }    return (ans.a[1][1]*9+ans.a[1][2]*5+ans.a[1][3]*3+ans.a[1][4])%mod;}int main(){    int T,cases=1;    scanf("%d",&T);    while(T--)    {        int n;        scanf("%d",&n);        if(n==0)            printf("Case %d: 1\n",cases++);        else if(n==1)            printf("Case %d: 4\n",cases++);        else if(n==2)            printf("Case %d: 9\n",cases++);        else        {            mat base;            memset(base.a,0,sizeof(base.a));            base.a[1][1]=1;            base.a[1][2]=3;            base.a[1][3]=2;            base.a[1][4]=7;            base.a[2][2]=3;            base.a[2][3]=2;            base.a[2][4]=7;            base.a[3][2]=1;            base.a[4][3]=1;            LL ans=pow_mat(base,n-2);            printf("Case %d: %lld\n",cases++,ans);        }    }}
原创粉丝点击