HDU 3306 Another kind of Fibonacci

来源:互联网 发布:淘宝翡翠拍卖会的骗局 编辑:程序博客网 时间:2024/05/21 09:13

这题和上次的CF的E题是差不多的,可能还要简单一点。

还是求Sn mod 一个数的值,n这么大,肯定不能暴力吧。。。还是只能找log n的做法。。。

这时候我们又想起了我们的矩阵君。。。

Sn=Sn-1+An^2

An+1^2=(xAn+yAn-1)^2=x^2*An^2+y^2*An-1^2+2*x*y*An-1*An

然后就很好搞了。。。构造出来的矩阵见代码就行了。。。

你要是问我咋想到的。。。这种你按递推一步一步写就好了。

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#define MAX 6#define MOD 10007using namespace std;typedef int i64;i64 a[MAX][MAX], b[MAX][MAX], c[MAX][MAX], buff[MAX][MAX], vec[MAX];void matCpy(i64 a[MAX][MAX], i64 b[MAX][MAX], int n) {    int i, j;        for (i = 0; i < n; ++i) {        for (j = 0; j < n; ++j) {            a[i][j] = b[i][j];        }    }}void norm(i64 a[MAX][MAX], int n) {    int i, j;        for (i = 0; i < n; ++i) {        for (j = 0; j < n; ++j) {            a[i][j] = (i == j);        }    }}void matMul(const i64 a[MAX][MAX], const i64 b[MAX][MAX], i64 c[MAX][MAX], int n) {    int i, j, k;        for (i = 0; i < n; ++i) {        for (j = 0; j < n; ++j) {            for (c[i][j] = k = 0; k < n; ++k) {                c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % MOD;            }        }    }}void matPow(i64 a[MAX][MAX], i64 b, i64 c[MAX][MAX], int n) {    for (norm(c, n); b; b >>= 1) {        if (b & 1) {            matMul(c, a, buff, n);            matCpy(c, buff, n);        }        matMul(a, a, buff, n);        matCpy(a, buff, n);    }}int main(){    int x,y;    int n;    while(scanf("%d%d%d",&n,&x,&y)!=EOF)    {        x=x%MOD,y=y%MOD;        x=(x+MOD)%MOD,y=(y+MOD)%MOD;        for(int i=0;i<4;i++)  for(int j=0;j<4;j++)  a[i][j]=0;        a[0][0]=1,a[0][1]=1;        a[1][1]=(x*x)%MOD,a[1][2]=(y*y)%MOD,a[1][3]=(2*x*y)%MOD;        a[2][1]=1,a[3][1]=x%MOD,a[3][3]=y%MOD;        matPow(a,n,b,4);        i64 ans=0;        for(int i=0;i<4;i++)  ans=(ans+b[0][i])%MOD;        printf("%d\n",(ans+MOD)%MOD);    }    return 0;}


0 0
原创粉丝点击