nyoj301递推求值

来源:互联网 发布:心中心网络道场 编辑:程序博客网 时间:2024/04/26 01:54

描述
给你一个递推公式:

f(x)=a*f(x-2)+b*f(x-1)+c

并给你f(1),f(2)的值,请求出f(n)的值,由于f(n)的值可能过大,求出f(n)对1000007取模后的值。

注意:-1对3取模后等于2

输入
第一行是一个整数T,表示测试数据的组数(T<=10000)
随后每行有六个整数,分别表示f(1),f(2),a,b,c,n的值。
其中0<=f(1),f(2)<100,-100<=a,b,c<=100,1<=n<=100000000 (10^9)

输出
输出f(n)对1000007取模后的值

样例输入
2
1 1 1 1 0 5
1 1 -1 -10 -100 3

样例输出
5
999896

这是矩乘的模板题了,需要注意的两点:数组不要开大,
每次%的时候 (+mod)%mod

这里写代码片#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#define LL long long using namespace std;const int mod=1000007;const int N=11;   ///这个地方取值大了后会T  QAQ LL f1,f2,a,b,c,p;int n;LL  MOD(LL x){    return (x%mod+mod)%mod;}struct node{    LL m[N][N];    node operator * (const node &a) const    {        node ans;        for (int i=1;i<=n;i++)            for (int j=1;j<=n;j++)            {                ans.m[i][j]=0;   //初值化,避免出错                 for (int k=1;k<=n;k++)                    ans.m[i][j]=(ans.m[i][j]+(LL)m[i][k]*a.m[k][j])%mod;  //            }        return ans;    }    node KSM(LL p)    {        p--;  ///         node ans=(*this),a=(*this);          while (p)        {            if (p&1)               ans=ans*a;            a=a*a;            p>>=1;        }         return ans;    }};int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%lld%lld%lld%lld%lld%lld",&f1,&f2,&a,&b,&c,&p);        node ans,m;        if (p==0){            printf("%lld\n",(f2-f1*b-c + mod)%mod);        }        else if (p==1){            printf("%lld\n",MOD(f1));        }        else if (p==2) {            printf("%lld\n",MOD(f2));        }        else{            m.m[1][1]=b;m.m[1][2]=1;m.m[1][3]=0;            m.m[2][1]=a;m.m[2][2]=0;m.m[2][3]=0;            m.m[3][1]=1;m.m[3][2]=0;m.m[3][3]=1;            n=3;            ans=m.KSM(p-2);//因为前两项已经给出,所以矩阵我们只有乘p-2次             printf("%lld\n",MOD(MOD(f2*ans.m[1][1])+MOD(f1*ans.m[2][1])+MOD(c*ans.m[3][1])));        }  //取%的限制真是丧心病狂,还有就是注意原始方程,不要乘错了     }    return 0;}
原创粉丝点击