XDOJ1013--时间工厂

来源:互联网 发布:it培训计划方案 编辑:程序博客网 时间:2024/05/19 06:49
Description

  zyf总是有很多奇异的想法,他最近常常幻想着以后能开这么一个工厂,可以把前三天里生产出来的东西拿到今天来拼在一起作为今天生产的东西。假如前三天生产出来的产品数分别是x,y,z,那么今天就能生产出x+y+z个。这样一来只要前三天的投入,接下来的工厂每一天都是0成本运作,但产品数却在极速增加,相当暴利。
  当然,为了防止地球被破坏,为了维护世界的和平,zyf是不会让工厂每天生产出来的东西超过1000000006个的,如果超过了,就不停减去1000000007,减到不超过为止。
  现在zyf想知道如果第一、二、三天分别生产a,b,c个产品的话,第n天会生产出多少产品呢?

Input
输入数据的第一行case数。
接下来每一行都有四个数字a,b,c,n(1<=a,b,c,n<=10^9),意义如上文.
Output
对于每个case输出一行,第n天生产的产品数。
Sample Input
2
1 2 3 4
1 1 1 5
Sample Output
6
5

解题思路:
第一眼感觉,这个题也太简单的吧!不就是简单的计算吗,后来才发现按着朴素的方法进行计算,时间是过不了的。那么如何快速计算呢,在网上一查,原来是转换为矩阵的计算,并对矩阵进行快速幂计算,复杂度就由O(n)变为O(lgn)。

#include<iostream>using namespace std;const int INF = 1000000007;const int D = 3;struct Matrix{    long long m[D][D];};Matrix X,A;void ZeroMatrix(Matrix& M){    for(int i=0;i<D;++i)        for(int j=0;j<D;++j)            M.m[i][j] = 0;}void initA(){    A.m[0][0] = 0;A.m[0][1] = 0;A.m[0][2] = 1;    A.m[1][0] = 1;A.m[1][1] = 0;A.m[1][2] = 1;    A.m[2][0] = 0;A.m[2][1] = 1;A.m[2][2] = 1;    ZeroMatrix(X);}Matrix mul(const Matrix& M,const Matrix& N){    Matrix T;    ZeroMatrix(T);    T.m[0][0] = (M.m[0][0]*N.m[0][0]+M.m[0][1]*N.m[1][0]+M.m[0][2]*N.m[2][0])%INF;    T.m[0][1] = (M.m[0][0]*N.m[0][1]+M.m[0][1]*N.m[1][1]+M.m[0][2]*N.m[2][1])%INF;    T.m[0][2] = (M.m[0][0]*N.m[0][2]+M.m[0][1]*N.m[1][2]+M.m[0][2]*N.m[2][2])%INF;    T.m[1][0] = (M.m[1][0]*N.m[0][0]+M.m[1][1]*N.m[1][0]+M.m[1][2]*N.m[2][0])%INF;    T.m[1][1] = (M.m[1][0]*N.m[0][1]+M.m[1][1]*N.m[1][1]+M.m[1][2]*N.m[2][1])%INF;    T.m[1][2] = (M.m[1][0]*N.m[0][2]+M.m[1][1]*N.m[1][2]+M.m[1][2]*N.m[2][2])%INF;    T.m[2][0] = (M.m[2][0]*N.m[0][0]+M.m[2][1]*N.m[1][0]+M.m[2][2]*N.m[2][0])%INF;    T.m[2][1] = (M.m[2][0]*N.m[0][1]+M.m[2][1]*N.m[1][1]+M.m[2][2]*N.m[2][1])%INF;    T.m[2][2] = (M.m[2][0]*N.m[0][2]+M.m[2][1]*N.m[1][2]+M.m[2][2]*N.m[2][2])%INF;    return T;}void fastPow(int n){    while(n!=0)    {        if(n&1)            X = mul(X,A);        n = n>>1;        A = mul(A,A);    }    cout<<X.m[0][2]<<endl;}int main(){    int nCase;    while(cin>>nCase)    {        for(int i=0;i<nCase;++i)        {            int n,a,b,c;            cin>>a>>b>>c>>n;            initA();            X.m[0][0] = a;X.m[0][1] = b;X.m[0][2] = c;            if(n<=3)                cout<<X.m[0][n-1]<<endl;            else                fastPow(n-3);        }    }}



0 0