求幂大法,矩阵快速幂,快速幂模板题--hdu4549

hdu-4549 求幂大法、矩阵快速幂、快速幂

题目

M斐波那契数列

Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 6217 Accepted Submission(s): 1902

Problem Description

M斐波那契数列F[n]是一种整数数列,它的定义如下:

F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )

现在给出a, b, n,你能求出F[n]的值吗?

Input

输入包含多组测试数据;
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )

Output

对每组测试数据请输出一个整数F[n],由于F[n]可能很大,你只需输出F[n]对1000000007取模后的值即可,每组数据输出一行。

Sample Input

0 1 0
6 10 2

Sample Output

0
60

思路

列出F_n的前几项可以知道,指数是0,1开始的斐波那契数列

代码

#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <cstdio>

using namespace std;

typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 5;
const int MOD = 1e9 + 7;

struct M
{
    LL m[2][2];
    M(){memset(m, 0, sizeof(m));}
};

LL Eular(LL n)
{
    LL ret = n;
    for(int i = 2;i * i <= n;++i)
    {
        if(n % i == 0)
        {
            ret = ret - ret / i;
            while(n % i == 0)
                n /= i;
        }
    }
    if(n > 1)
        ret = ret - ret / n;
    return ret;
}

LL m = Eular(MOD);

M mul(M a, M b)
{
    M ret;
    for(int i = 0;i < 2;++i)
        for(int j = 0;j < 2;++j)
            for(int k = 0;k < 2;++k)
            ret.m[i][j] = (ret.m[i][j] + a.m[i][k] * b.m[k][j] % m) % m;//注意这里因为是幂,所以是模Eular(MOD)
    return ret;
}

M M_pow(M a, int b)
{
    M ret;
    ret.m[0][0] = 1, ret.m[1][1] = 1;
    while(b)
    {
        if(b & 1)
            ret = mul(ret, a);
        a = mul(a, a);
        b >>= 1;
    }
    return ret;
}

LL q_pow(LL a, LL b)
{
    LL ret = 1;
    a %= MOD;
    while(b)
    {
        if(b & 1)
            ret = (ret * a) % MOD;
        a = (a * a) % MOD;
        b >>= 1;
    }
    return ret;
}

int main()
{
    LL a, b, n;
    while(cin >> a >> b >> n)
    {
        if(!n)
        {
            cout << a % MOD << endl;
            continue;
        }
        M f, k;
        f.m[0][0] = 1;
        k.m[0][0] = k.m[0][1] = k.m[1][0] = 1;
        f = mul(f, M_pow(k, n - 1));
        //cout << f.m[0][1] << " " << f.m[0][0] << endl;
        cout << ((q_pow(a, f.m[0][1] % m) % MOD) * (q_pow(b, f.m[0][0] % m) % MOD)) % MOD << endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/shuizhidao/p/10623740.html

时间: 2024-07-31 11:14:08

求幂大法,矩阵快速幂,快速幂模板题--hdu4549的相关文章

【BZOJ2179】FFT快速傅立叶 高精度乘模板题

广告: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44015679"); } 题解: 其实没什么题解,只是贴个模板+理解注释 代码: #include <cmath> #include <cstdio> #include <cstring> #inc

算法初步:快速乘,快速幂,矩阵快速幂

原创 by zoe.zhang 在刷题的时候遇到了问题,就是当循环或者递推的次数非常大的情况下获取一定结果,这个时候如果作普通运算,那么很容易就超时了,而且有时候结果也大得超范围了,即使是long long类型的也放不下,然后给了提示说是运用快速幂的思想.所以这里对快速幂做了一点思考和探讨. 1.快速乘,快速幂,矩阵快速幂三者的关系 不管是快速乘,还是快速幂算法,实际上都包含了分解问题的思想在里面,将O(n)的复杂度降到O(lgn).学习的时候,一般学习快速幂算法,再由此推广去解决矩阵快速幂问题

HDU 1575 &amp;&amp; 1757 矩阵快速幂&amp;&amp;构造矩阵入门

HDU 1575 Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2912    Accepted Submission(s): 2167 Problem Description A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input 数据的第一行是一个T,表示有T组数据.每组

快速乘、快速幂(矩阵快速幂)

当mod一个大数p的时候,还有进行乘法的时候可能会爆long long的时候,就用快速乘或者快速幂. 参考:http://www.cnblogs.com/whywhy/p/5066730.html 先上模板: 快速乘: ll multi(ll a,ll b,ll m) { ll ans=0; while(b) { if(b&1) (ans+=a) %= m; (a=a*2) %= m; b/=2; } return ans; } 快速幂: ll pow_mod(ll a,ll b,ll m) {

数论——快速幂,模运算及快速幂求逆元

一.快速幂 原理: 快速幂的原理十分简单. ak=a2^0*a2^1*a2^2*…a2^x,其中k=20+21+22+…+2x. 这显然是正确的.因为任何一个数都可以表示成二进制. 接下去利用位运算实现即可. 代码实现 模板题链接:快速幂 代码模板如下:时间复杂度O(logk) int qmi(int a,int k,int p) { int res=1%p; while(k) { if(k&1)res=(long long)res*a%p; a=(long long)a*a%p; k>&g

北邮机试 矩阵幂计算器 需要二刷 *快速幂问题的扩展

基本思想: 快速幂的拓展,把快速幂乘法的指数部分改成矩阵即可: 关键点: 无: #include<iostream> #include<string> #include<vector> #include<map> #include<set> using namespace std; const int maxn = 15; int n, k; vector<vector<int>> multi(vector<vect

【HDOJ5950】Recursive sequence(矩阵乘法,快速幂)

题意:f[1]=a,f[2]=b,f[i]=2f[i-2]+f[i-1]+i^4(i>=3),多组询问求f[n]对2147493647取模 N,a,b < 2^31 思路:重点在于i^4的处理 对于i转移矩阵中可以记录下它的0,1,2,3,4次项 i的幂又可以由i-1的幂运算得出,最后推出的系数是二项式展开的系数 试试新的矩乘模板 1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #inc

快速乘法/快速幂 算法

快速幂算法可以说是ACM一类竞赛中必不可少,并且也是非常基础的一类算法,鉴于我一直学的比较零散,所以今天用这个帖子总结一下 快速乘法通常有两类应用:一.整数的运算,计算(a*b) mod c  二.矩阵快速乘法 一.整数运算:(快速乘法.快速幂) 先说明一下基本的数学常识: (a*b) mod c == ( (a mod c) * (b mod c) ) mod c //这最后一个mod c 是为了保证结果不超过c 对于2进制,2n可用1后接n个0来表示.对于8进制,可用公式 i+3*j ==

hdu 5690 2016&quot;百度之星&quot; - 初赛(Astar Round2A) All X 快速二次幂 || 寻找周期

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5690 题意:m个数字全为x mod k ?= c;其中m <= 1010,0 < c,k <= 10,000; 法1:xxx = (10m-1)/9*x;但是n太大,需要同时mod.去除分母将式子变为:10m*x%(9k) - x%(9k) =? 9c ;其中 10m 快速二次幂即可: 时间复杂度为O(logn) 法2: 由于m个x数的产生对于mod具有可拆分性,所以直接求解周期即可: #i