HDU2256&&HDU4565:给一个式子的求第n项的矩阵快速幂

HDU2256

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2256

题意:求(sqrt(2)+sqrt(3))^2n%1024是多少。

这个题算是hdu4565的一个常数版本了,所以我们先说这道题。对于这道题的做法我们可以计算((sqrt(2)+sqrt(3))^2)^n=(5+2*sqrt(6))^n,对于(5+2*sqrt(6))^n我们知道答案必定是以an+bn*sqrt(6),而对于下一项我们只需要求(an+bn*sqrt(6))*(5+2*sqrt(6))=5*an+12*bn+2*an*sqrt(6)+5*bn*sqrt(6),所以a(n+1)=5*an+12*bn; b(n+1)=2*an+5*bn。有了这个递推式我们就可以构造矩阵求an,bn。

这里还有一点对于(5+2*sqrt(6))^n=an+bn*sqrt(6); 同理(5-2*sqrt(6))^n=an-bn*sqrt(6);两式相加(5+2*sqrt(6))^n+(5-2*sqrt(6))^n=2*an,当n趋于无穷的时候lim(5-2*sqrt(6))^n=0,因为5-2*sqrt(6)<1。

所以我们可以得到答案(5+2*sqrt(6))^n约等于2*an,且实际值是比2*an要小的且小于2*an-1要大的,所以由题目的意思我们向下取整,ans=2*an-1;具体看代码,其他都是矩阵快速幂的模板。

//Author: xiaowuga
#include <bits/stdc++.h>
#define maxx INT_MAX
#define minn INT_MIN
#define inf 0x3f3f3f3f
#define n 2
#define MOD 1024
using namespace std;
typedef long long ll;
struct Matrix{
    ll mat[4][4];
    Matrix operator * (const Matrix & m) const{
        Matrix tmp;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++){
                tmp.mat[i][j]=0;
                for(int k=0;k<n;k++){
                    tmp.mat[i][j]+=mat[i][k]*m.mat[k][j]%MOD;
                    tmp.mat[i][j]%=MOD;
                }
            }
        return tmp;
    }
};
Matrix POW(Matrix &m,int k){
    Matrix ans;
    memset(ans.mat,0,sizeof(ans.mat));
    for(int i=0;i<n;i++) ans.mat[i][i]=1;
    while(k){
        if(k&1) ans=ans*m;
        k/=2;
        m=m*m;
    }
    return ans;
}
int main() {
    ios::sync_with_stdio(false);cin.tie(0);
    ll T,num;
    cin>>T;
    while(T--){
        cin>>num;
        Matrix m;
        m.mat[0][0]=5; m.mat[0][1]=12; m.mat[1][0]=2; m.mat[1][1]=5;
        Matrix ans=POW(m,num-1);
        ll sum=0,f[2]={5,2};
        for(int i=0;i<2;i++)
            sum+=ans.mat[0][i]*f[i]%MOD;
        sum%=MOD;
        ll x=(2*sum-1)%MOD;
        cout<<x<<endl;
    }
    return 0;
}

HDU4565

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4565

题意:算是上面那道题的一个升级版本啦。现在是a和b不是固定的的常数了。和上面的做法一样。注意题目中给出a-sqrt(b)<1的条件,所以基本和上道题是一样的了,类比一下吧!很简单的。但是这里是向上取整,所以答案是2*an。具体看代码吧。由于上面那道题在常数情况下已经说得很明白了。这道题就不说了

//Author: xiaowuga
#include <bits/stdc++.h>
#define maxx INT_MAX
#define minn INT_MIN
#define inf 0x3f3f3f3f
#define size 2
int MOD;
using namespace std;
typedef long long ll;
struct Matrix{
    ll mat[4][4];
    void clear(){
        memset(mat,0,sizeof(mat));
    }
    Matrix operator * (const Matrix & m) const{
        Matrix tmp;
        for(int i=0;i<size;i++)
            for(int j=0;j<size;j++){
                tmp.mat[i][j]=0;
                for(int k=0;k<size;k++){
                    tmp.mat[i][j]+=mat[i][k]*m.mat[k][j]%MOD;
                    tmp.mat[i][j]%=MOD;
                }
            }
        return tmp;
    }
};
Matrix POW(Matrix &m,int k){
    Matrix ans;
    memset(ans.mat,0,sizeof(ans.mat));
    for(int i=0;i<size;i++) ans.mat[i][i]=1;
    while(k){
        if(k&1) ans=ans*m;
        k/=2;
        m=m*m;
    }
    return ans;
}
int main() {
    ios::sync_with_stdio(false);cin.tie(0);
    ll  a,b,n;
    while(cin>>a>>b>>n>>MOD){
        Matrix m;
        m.clear();
        m.mat[0][0]=m.mat[1][1]=a%MOD;
        m.mat[0][1]=b%MOD;m.mat[1][0]=1;
        Matrix ans=POW(m,n-1);
        ll sum=(ans.mat[0][0]*a%MOD+ans.mat[0][1]%MOD)%MOD;
        cout<<2*sum%MOD<<endl;
    }
    return 0;
}
时间: 2024-12-21 18:50:07

HDU2256&&HDU4565:给一个式子的求第n项的矩阵快速幂的相关文章

2018ICPC焦作- Poor God Water 求递推式+矩阵快速幂

题目链接:https://nanti.jisuanke.com/t/31721 题意:一个孩子吃饭,有meat, fish 和 chocolate 三种食物可以选.要求连续三顿饭食物不能完全相同,鱼和肉的前一顿和后一顿不能都是巧克力,巧克力的左右两边不能同时出现鱼和肉. 思路:分九种情况,求出递推式,写出标准矩阵,用矩阵快速幂. 代码: #include <iostream> #include <stdio.h> #include <string.h> #define

hdu 1575 求一个矩阵的k次幂 再求迹 (矩阵快速幂模板题)

Problem DescriptionA为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input数据的第一行是一个T,表示有T组数据.每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据.接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容. Output对应每组数据,输出Tr(A^k)%9973. Sample Input22 21 00 13 999999991 2 34

HDU - 1588 Gauss Fibonacci (矩阵快速幂+二分求等比数列和)

Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r a very clever boy. So if you wanna me be your GF, you should solve the problem called GF~. " How good an opportunity that Gardon can not give up! The "Prob

HDU4565 So Easy! 矩阵快速幂外加数学

easy 个屁啊,一点都不easy,题目就是要求公式的值,但是要求公式在最后的取模前的值向上取整,再取模,无脑的先试了快速幂 double  fmod来做,结果发现是有问题的,这题要做肯定得凑整数,凑整  题目给 a+√b 那么加上a-√b就可以了,可是这样加上后面怎么处理还得减去,想了半年也想不出来, 原来用了负数的共轭思想,还有就是题目给的b的范围 是 ((a-1)*(a-1),a*a),所以 a-√b的值的 无论多少次方 的值都是小于1的,所以对于原式子 改装成 ((a + √b) ^n+

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数列

poj 3070 Fibonacci 【矩阵快速幂 求第N个斐波那契数%1000】

Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11123   Accepted: 7913 Description In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn ? 1 + Fn ? 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequenc

hdu1588 Gauss Fibonacci(矩阵快速幂+二分求矩阵等比和)

题目: Gauss Fibonacci Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2858    Accepted Submission(s): 1186 Problem Description Without expecting, Angel replied quickly.She says: "I'v heard that y

HDOJ Queuing 2604【求矩阵+矩阵快速幂】

Queuing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3528    Accepted Submission(s): 1590 Problem Description Queues and Priority Queues are data structures which are known to most computer

hdu4686 简单的矩阵快速幂求前n项和

HDU4686 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4686 题意:题目说的很清楚了,英语不好的猜也该猜懂了,就是求一个表达式的前n项和,矩阵快速幂一般多加一行一列来完成这个加的操作.具体看代码吧.比较简单,唯一有一点坑的地方,就是ax和bx可能比较大,在求ax*bx的时候,要考虑溢出的问题,需要先mod.其他没有了,直接看代码吧! //Author: xiaowuga #include <bits/stdc++.h> #define