简单数论之矩阵构造

其实矩阵构造就是对公式的化简,最后运用矩阵快速幂求值

下面来看一题

Everybody knows Fibonacci numbers, now we are talking about the Tribonacci numbers: T[0] = T[1] = T[2] = 1; T[n] = T[n - 1] + T[n - 2] + T[n - 3] (n >= 3)
Given a and b, you are asked to calculate the sum from the ath Fibonacci number to the bth Fibonacci number, mod 1,000,000,007, that is (T[a] + T[a + 1] + ... + T[b]) % 1,000,000,007.

There are multiple cases (no more than 100).
Each case contain two non-negative integers a b(a <= b and a, b < 1,000,000,000)

For each case, output the sum % 1,000,000,007.

T[n] = T[n - 1] + T[n - 2] + T[n - 3]

左边累加,右边累加我们发现

sum[n] = sum[n - 1] + sum[n - 2] + sum[n - 3]

1  1  1

1  0  0

0  1  0

sum[n-1]  0   0

sum[n-2]  0   0

sum[n-3]  0   0

代码:

#include<iostream>
#include<cstdio>
using namespace std;
#define M 1000000007
struct mat
{
    int ans[4][4];
};

mat I,MID;
mat cal(mat a,mat b)
{
    mat c;
    int i,j,k;
    for(i=0;i<4;i++)
        for(j=0;j<4;j++)
        {
            c.ans[i][j]=0;
            for(k=0;k<4;k++)
                c.ans[i][j]+=a.ans[i][k]*b.ans[k][j];
                c.ans[i][j]%=M;
        }
    return c;
}

mat atl(int n)
{
    mat res=MID;
    mat mid=I;
    while(n){
    if(n&1)
        res=cal(res,mid);
        mid=cal(mid,mid);
        n>>=1;}
        return res;
}

int main()
{
    int k,i,j;
    int a,b;
    while(scanf("%d%d",&a,&b)!=-1)
    {
            I.ans[0][0]=1;
            I.ans[0][1]=1;
            I.ans[0][2]=1;
            MID.ans[0][0]=1;
            MID.ans[0][1]=1;
            MID.ans[0][2]=1;
            MID.ans[1][0]=1;
            MID.ans[2][1]=1;
                mat l=atl(b-2);
                mat g=atl(a-3);
        printf("%d\n",l.ans[0][0]-g.ans[0][0]);
    }
    return 0;
}

时间: 2024-12-24 15:30:37

简单数论之矩阵构造的相关文章

hdu 1395 2^x mod n = 1 (简单数论)

题目大意: 求出一个最小的x 使得 2的x次方对n取模为1 思路分析: 若要 a*b%p=1  要使得b存在 则 gcd (a,p)=1. 那么我们应用到这个题目上来. 当n为偶数 2^x 也是偶数,那么gcd 肯定不是1.故这个是不存在的. 那么n为奇数的时候,也就一定是1了. 所以直接暴力找. #include <iostream> #include <cstdio> using namespace std; int main() { int n; while(scanf(&q

hdu 3326 Another kind of Fibonacci (矩阵构造)

题目大意: 描述了另外一种斐波那契 F[n] = x*F[n-1] + y*F[n-2]; 求segma(F[i]^2): 思路分析: 构造矩阵的详细 请戳我 构造矩阵可以得到 中间矩阵为 1 1 0 0 0 x^2      y^2   2*x*y 0 1 0 0 0 x 0 y #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <

HDOJ 1163 Eddy&#39;s digital Roots(简单数论)

[思路]:http://blog.csdn.net/iamskying/article/details/4738838 求解思路: 现在分析一个问题,假设将十位数为a,个位数为b的一个整数表示为ab,则推导得 ab*ab = (a*10+b)*(a*10+b) = 100*a*a+10*2*a*b+b*b 根据上式可得:root(ab*ab) = a*a+2*a*b+b*b = (a+b)*(a+b);[公式一] 同理也可证得:root(ab*ab*ab) = (a+b)*(a+b)*(a+b)

简单数论

1.求gcd,算法为欧几里德(辗转相除法) 2.解一元二次方程,算法为扩展欧几里德 3.求素数,算法为埃氏筛法 4.快速进行幂运算,算法快速幂(反复平方) 5.解线性同余方程,求逆元(基于exgcd) 6.其它用来优化模运算的定理,欧拉定理(费马小定理),相应的函数欧拉函数 简单数论

简单数论之整除&质因数分解&唯一分解定理

[整除] 若a被b整除,即a是b的倍数,那么记作b|a("|"是整除符号),读作"a整除b"或"b能被a整除".a叫做b的约数(或因数),b叫做a的倍数. 简单数论之整除&质因数分解&唯一分解定理 原文地址:https://www.cnblogs.com/zjd-ac/p/10351608.html

矩阵构造

[转]http://www.cnblogs.com/frog112111/archive/2013/05/19/3087648.html 讲得不是一般的好: Fibonacci数列:F(0)=Fibonacci数列:F(0)=1 , F(1)=1 , F(n)=F(n-1)+F(n-2) 我们以前快速求Fibonacci数列第n项的方法是 构造常系数矩阵 (一)   Fibonacci数列f[n]=f[n-1]+f[n-2],f[1]=f[2]=1的第n项快速求法(不考虑高精度) 解法: 考虑1

HDU - 5015 233 Matrix (矩阵构造)

Problem Description In our daily life we often use 233 to express our feelings. Actually, we may say 2333, 23333, or 233333 ... in the same meaning. And here is the question: Suppose we have a matrix called 233 matrix. In the first line, it would be

简单螺旋打印矩阵 - 直接, 好理解

打印螺旋矩阵的一种简单办法 , C 语言实现 #include <stdio.h> #define N 30 static int val = 10; int arr[N][N]; void print_row(int row_cur, int col_start, int col_end, int left_to_right){ int col_cur = col_start; if( col_start < 0 || col_end < 0) return; if( left_

简单递推公式转换矩阵求解

对于许多递推题目,由于数据范围太大直接循环写会爆掉,这时首先想到的就是矩阵优化,把递推式转换成01矩阵通过快速幂优化. 比如最简单的斐波纳挈,如果n非常大,循环递推肯定是不合适的,那么可以考虑下面的公式  (f[n],f[n-1])=(f[n-1],f[n-2])*A; 这里的A是一个01矩阵,此时的A={1,1,1,0} 2*2的矩阵,    可想而知 f[3] = A的n-2次幂*(f[2],f[1]);   形如斐波纳挈的递推公式转换矩阵都很简单, 顺便附上POJ3070的 斐波纳挈转矩阵