矩阵快速幂专题(持续更新ing.avi)

来源:互联网 发布:淘宝如何查购买记录 编辑:程序博客网 时间:2024/05/18 00:34
Fibonacci数列(七)时间限制:2000 ms  |  内存限制:65535 KB难度:4描述   Fibonacci数列的第一项f(0)=1,f(1)=1,现在我们定义第n项f(n)=x*f(n-1)+y*f(n-2)。我们现在需要计算S(n)=f(0)2+f(1)2+f(2)2+...+f(n)2。输入有多组测试数据(<=10000),每行输入3个数,n,x,y,(2<=n,x,y<=100000000);输出输出S(n)%10007的结果样例输入2 1 13 2 3样例输出6196
什么都不用看,上来直接构造矩阵:s(n)=f(0)^2+f(1)^2+...+f(n)^2f(n)=x*f(n-1)+y*f(n-2)直接f(n)^2=x^2*f(n-1)^2+y^2*f(n-2)^2+2xy*f(n-1)f(n-2)直接构造个四维的矩阵:我们令a=x^2, b=y^2, c=2xy这里f(n-1)f(n)化作f(n-1)(x*f(n-1)+y*f(n-2))=x*f(n-1)^2+y*f(n-1)f(n-2),这样就可以找出f(n-1)f(n-2)->f(n)f(n-1);| a b c 0 | * |  f(n-1)^2   | = | f(n)^2   || 1 0 0 0 |   |  f(n-2)^2   |   |f(n-1)^2  || x 0 y 0 |   |f(n-1)f(n-2) |   |f(n)f(n-1)|| a b c 1 |   |   s(n-1)    |   | s(n)     |这里呢x,y比较大,作为系数,我们可以先取模。然后矩阵快速幂就可以了。
#include<iostream>#include<cstring>#include<cstdlib>#include<algorithm>#include<cctype>#include<cmath>#include<ctime>#include<string>#include<stack>#include<deque>#include<queue>#include<list>#include<set>#include<map>#include<cstdio>#include<limits.h>#define fir first#define sec second#define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin)#define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout)#define mes(x, m) memset(x, m, sizeof(x))#define pii pair<int, int>#define Pll pair<ll, ll>#define INF 1e9+7#define Pi 4.0*atan(1.0)#define MOD 1000000007#define lowbit(x) (x&(-x))#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define ls rt<<1#define rs rt<<1|1typedef long long ll;typedef unsigned long long ull;const double eps = 1e-12;const int maxn = 4;using namespace std;inline ll read(){    ll x(0),f(1);    char ch=getchar();    while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();    return x*f;}struct matrix{    int mat[4][4];    void init(){        mes(mat, 0);        for(int i = 0; i < 4; ++i){            mat[i][i] = 1;        }    }    void clear(){        mes(mat, 0);    }    void output(){        for(int i = 0; i < 4; ++i){            for(int j = 0; j < 4; ++j){                cout << mat[i][j] << " ";            }            printf("\n");        }    }    matrix operator*(const matrix &base){        matrix tmp;        tmp.clear();        for(int i = 0; i < 4; ++i){            for(int j = 0; j < 4; ++j){                for(int k = 0; k < 4; ++k){                    tmp.mat[i][j] = (tmp.mat[i][j] + mat[i][k]*base.mat[k][j])%10007;;                }            }        }        return tmp;    }    friend matrix operator^(const matrix &base, const int &pow_n){        matrix res;        matrix tmp = base;        res.init();        int pow_m = pow_n;        while(pow_m){            if(pow_m&0x01){                res=res*tmp;            }            tmp=tmp*tmp;            pow_m >>= 1;        }        return res;    }};int main(){    int n, x, y, a, b, c;    while(cin>>n>>x>>y){        x %= 10007;        y %= 10007;        a = x*x%10007;        b = y*y%10007;        c = x*y*2%10007;        matrix base;        base.clear();        base.mat[0][0] = base.mat[3][0] = a;        base.mat[0][1] = base.mat[3][1] = b;        base.mat[0][2] = base.mat[3][2] = c;        base.mat[1][0] = base.mat[3][3] = 1;        base.mat[2][0] = x;        base.mat[2][2] = y;        matrix p;        p.clear();        p.mat[0][0] = p.mat[1][0] = p.mat[2][0] = 1;        p.mat[3][0] = 2;        base = base^(n-1);        p = base*p;        cout << (p.mat[3][0]+10007)%10007 << endl;    }    return 0;}
0 0
原创粉丝点击