[矩阵快速幂] hdu 3936 FIB Query

题意:

求定义y(x)=4*x-1

给L、R求 fib(y(L))~fib(y(R))的和

思路:

和之前做的一道题类似。

定于Fib为

1 1

1 0

我们的第一项就是x=1时的 就是Fib^3

然后下一项其实就是fib(3+4)=Fib^3*Fib^4

所以递推矩阵就是Fib^4

然后求和利用快速的求法

Fib E

0    E

这样运算N次右上角的矩阵就是我们要的和的矩阵了

然后就是答案了~!

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
#define ll __int64
__int64 mod=1000000007;
struct matrix
{
    __int64 mat[5][5];
};
matrix matadd(matrix a,matrix b,int n,int m)
{
    int i,j;
    matrix c;
    memset(c.mat,0,sizeof(c.mat));
    for(i=0; i<n; i++)  for(j=0; j<n; j++)  c.mat[i][j]=(a.mat[i][j]+b.mat[i][j])%m;
    return c;
}
matrix matmul(matrix a,matrix b,int n,int m)
{
    int i,j,k;
    matrix c;
    memset(c.mat,0,sizeof(c.mat));
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {
            for(k=0; k<n; k++)
            {
                c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
                c.mat[i][j]%=m;
            }
        }
    }
    return c;
}
matrix matpow(matrix a,__int64 k,int n,int m)
{
    matrix b;
    int i;
    memset(b.mat,0,sizeof(b.mat));
    for(i=0; i<n; i++) b.mat[i][i]=1;
    while(k)
    {
        if(k&1) b=matmul(a,b,n,m);
        a=matmul(a,a,n,m);
        k>>=1;
    }
    return b;
}
matrix matsum(matrix a,__int64 k,int n,int m)
{
    if(k<=0) return matpow(a,0,n,m);
    int x=(k+1)/2;
    matrix b,ans;
    b=matsum(a,x-1,n,m);
    ans=matadd(b,matmul(b,matpow(a,x,n,m),n,m),n,m);
    if(k%2==0)  ans=matadd(ans,matpow(a,k,n,m),n,m);
    return ans;
}
ll solve(ll x)
{
    x--;
    if(x<0) return 0;
    matrix a,b,c,ans;
    memset(a.mat,0,sizeof(a.mat));
    memset(b.mat,0,sizeof(b.mat));
    memset(c.mat,0,sizeof(c.mat));
    c.mat[0][0]=c.mat[0][1]=c.mat[1][0]=1;
    a=matpow(c,3,2,mod);
    b=matpow(c,4,2,mod);
    b.mat[0][2]=b.mat[1][3]=b.mat[2][2]=b.mat[3][3]=1;
    ans=matpow(b,x+1,4,mod);
    b.mat[0][0]=ans.mat[0][2];
    b.mat[0][1]=ans.mat[0][3];
    b.mat[1][0]=ans.mat[1][2];
    b.mat[1][1]=ans.mat[1][3];
    ans=matmul(a,b,2,mod);
    return ans.mat[0][1];
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        ll x,y;
        scanf("%I64d%I64d",&x,&y);
        ll ans=solve(y)-solve(x-1);
        ans=(ans%mod+mod)%mod;
        printf("%I64d\n",ans);
    }
    return 0;
}
时间: 2024-10-01 03:18:51

[矩阵快速幂] hdu 3936 FIB Query的相关文章

矩阵快速幂——HDU 2604

对应HDU题目:点击打开链接 Queuing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3114    Accepted Submission(s): 1419 Problem Description Queues and Priority Queues are data structures which are known t

递推+矩阵快速幂 HDU 2065

1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 5 using namespace std; 6 7 //矩阵大小上限 8 const int SIZ=100; 9 int MOD=100; 10 11 //矩阵大小为n*m,初始化全部为0 12 struct mat 13 { 14 int n,m; 15 int ar[SIZ][SIZ]; 16 mat() 17 { 18 memset

[矩阵快速幂] hdu 5015 233 Matrix

之前各种犯傻 推了好久这个东西.. 后来灵关一闪  就搞定了.. 矩阵的题目,就是构造矩阵比较难想! 题意:给出一个矩阵的第一列和第一行(下标从0开始),(0,0)位置为0, 第一行为,233,2333,23333...一次加个3, 第一列为输入的n个数. 然后从(1,1)位置开始,等于上面的数加左边的数,问(n+1,m+1)的数是多少,也就是右下角的数 思路: 把矩阵画出来: |   0     233   2333  | |  b0     b1     b2     | |  c0    

矩阵快速幂 HDU 4565 So Easy!(简单?才怪!)

题目链接 题意: 思路: 直接拿别人的图,自己写太麻烦了~ 然后就可以用矩阵快速幂套模板求递推式啦~ 另外: 这题想不到或者不会矩阵快速幂,根本没法做,还是2013年长沙邀请赛水题,也是2008年Google Codejam Round 1A的C题. #include <bits/stdc++.h> typedef long long ll; const int N = 5; int a, b, n, mod; /* *矩阵快速幂处理线性递推关系f(n)=a1f(n-1)+a2f(n-2)+.

矩阵快速幂 [HDU 4549] M斐波那契数列

M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1609    Accepted Submission(s): 460 Problem Description M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = aF[1] = bF[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a,

[矩阵快速幂] hdu 3893 Drawing Pictures

题意: 给长度N的格子,有六种颜料ABCDEF, 要求涂满N个格子的方案数,并且保证是对称的,并且相邻的格子颜色不同,并且不出现ABCDEF这个序列. 思路: 受到中午那题,思维大开 首先因为颜色相邻不能相同且要对称,所以N为偶数答案为0. 接着先假设有这六种状态0(代表没颜色限制),A,AB,ABC,ABCD,ABCDE 然后初始状态为(5,1,0,0,0,0)两两之间构成转换关系 结果提交WA了 发现这题真是丧心病狂 如果是这样FEDCBABCDEF 这样对称的话就会跪 所以还有5个状态 F

[矩阵快速幂] hdu 4990 Reading comprehension

题意: 初始值为零,后面奇数项成二加一,偶数项乘二. 思路: 其实区别就在于这个加一. 就是构造一个-1每次相成,然后1-1+1就ok了. 就是 |  -1   1   0  | | -1  1  0 | * |   0   1   1  |  =  | 1  0  1 | |   0   0   2  | 依次类推就好了. 代码: #include"cstdlib" #include"cstdio" #include"cstring" #inc

Codeforces 719E [斐波那契区间操作][矩阵快速幂][线段树区间更新]

/* 题意:给定一个长度为n的序列a. 两种操作: 1.给定区间l r 加上某个数x. 2.查询区间l r sigma(fib(ai)) fib代表斐波那契数列. 思路: 1.矩阵操作,由矩阵快速幂求一个fib数根据矩阵的乘法结合率,A*C+B*C=(A+B)*C; 这样可以通过线段树维护某个区间2*1矩阵的和. 2.时限卡的紧...用我的矩阵乘法板子TLE了.所以把板子里边的三重循环改成手工公式... 3.注意(a+b)%mod.这种,改成if(a+b>=mod)a+b-mod这种形式时间几乎

hdu 3221 Brute-force Algorithm(快速幂取模,矩阵快速幂求fib)

http://acm.hdu.edu.cn/showproblem.php?pid=3221 一晚上搞出来这么一道题..Mark. 给出这么一个程序,问funny函数调用了多少次. 我们定义数组为所求:f[1] = a,f[2] = b, f[3] = f[2]*f[3]......f[n] = f[n-1]*f[n-2].对应的值表示也可为a^1*b^0%p,a^0*b^1%p,a^1*b^1%p,.....a^fib[n-3]*b^fib[n-2]%p.即a,b的指数从n=3以后与fib数列