HDU 2256 Problem of Precision(矩阵快速幂)+ HDU 4565

HDU 2256

题意:

计算?(2√+3√)2n?mod1024

思路:

∵f(n)=(2√+3√)2n=(5+26√)n=An+Bn?6√

∴f(n?1)=An?1+Bn?1?6√

又∵f(n)=(5+26√)?f(n?1)

∴f(n)=(5?An?1+12?Bn?1)+(2?An?1+5?Bn?1)?6√

所以递推矩阵就是:

(52125)?(An?1Bn?1)=(AnBn)

A1=5,B1=2.

然后套矩阵快速幂模板即可求出An,Bn.

又∵(5+26√)n=An+Bn?6√

∴(5?26√)n=An?Bn?6√

∴(5+26√)n+(5?26√)n=2An

又∵(5?26√)n<1

∴?(5+26√)n?=2An?1

所以最后答案就是2An?1

代码:

/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>

using namespace std;

#define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define mp make_pair
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL;

const int mod = 1024;
const int maxn = 4;
struct Matrix{
    int n,m;
    lint a[maxn][maxn];
    Matrix(int n , int m){
        this->n = n;
        this->m = m;
        cls(a);
    }
    Matrix operator * (const Matrix &tmp){
        Matrix res(n,tmp.m);
        for(int i = 0 ; i < n ; i++){
            for(int j = 0 ; j < tmp.m ; j++){
                for(int k = 0 ; k < m ; k++){
                    res.a[i][j] = (res.a[i][j] + (a[i][k] * tmp.a[k][j]) % mod) % mod;
                }
            }
        }
        return res;
    }
};

void Matrix_print(Matrix x){
    for(int i = 0 ; i < x.n ; i++){
        for(int j = 0 ; j < x.m ; j++) cout << x.a[i][j] << ‘ ‘;
        cout << endl;
    }
}
Matrix fast_pow(Matrix x ,int n){
    Matrix res(x.n,x.m);
    for(int i = 0 ; i <  x.n ; i++) res.a[i][i] = 1;
    while(n){
        if(n&1)
            res = res * x;
        x = x*x;
        n >>= 1;
        //Matrix_print(res);
        //cout << endl;
    }
    return res;
}

void solve(){
    lint n;
    cin >> n;
    if(n == 1){
        cout << 9 << endl;
        return;
    }
    Matrix base(2,1);
    Matrix fun(2,2);
    base.a[0][0] = 5;
    base.a[1][0] = 2;
    fun.a[0][0] = 5;
    fun.a[0][1] = 12;
    fun.a[1][0] = 2;
    fun.a[1][1] = 5;
    fun = fast_pow(fun,n-1);
    base = fun * base;
    cout << (2*base.a[0][0] - 1) % mod << endl;
}

int main(){
    int t ; cin >> t;
    while(t--){
        solve();
    }
    return 0;
}

附送HDU 4565代码:

/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>

using namespace std;

#define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define mp make_pair
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL;
lint mod;
lint n , a , b ;
const int maxn = 4;
struct Matrix{
    int n,m;
    lint a[maxn][maxn];
    Matrix(int n , int m){
        this->n = n;
        this->m = m;
        cls(a);
    }
    Matrix operator * (const Matrix &tmp){
        Matrix res(n,tmp.m);
        for(int i = 0 ; i < n ; i++){
            for(int j = 0 ; j < tmp.m ; j++){
                for(int k = 0 ; k < m ; k++){
                    res.a[i][j] = (res.a[i][j] + (a[i][k] * tmp.a[k][j]) % mod) % mod;
                }
            }
        }
        return res;
    }
};

void Matrix_print(Matrix x){
    for(int i = 0 ; i < x.n ; i++){
        for(int j = 0 ; j < x.m ; j++) cout << x.a[i][j] << ‘ ‘;
        cout << endl;
    }
}
Matrix fast_pow(Matrix x ,int n){
    Matrix res(x.n,x.m);
    for(int i = 0 ; i <  x.n ; i++) res.a[i][i] = 1;
    while(n){
        if(n&1)
            res = res * x;
        x = x*x;
        n >>= 1;
        //Matrix_print(res);
        //cout << endl;
    }
    return res;
}

void solve(){
    if(n == 1){
        lint ans = (lint)( a + ceil( sqrt( b * 1.0 ) ) ) % mod;
        cout << ans << endl;
        return;
    }
    Matrix base(2,1);
    Matrix fun(2,2);
    base.a[0][0] = a % mod;
    base.a[1][0] = 1;
    fun.a[0][0] = a % mod;
    fun.a[0][1] = b % mod;
    fun.a[1][0] = 1;
    fun.a[1][1] = a % mod;
    fun = fast_pow(fun,n-1);
    base = fun * base;
    cout << (2 * base.a[0][0]) % mod << endl;
}

int main(){
    while(cin >> a >> b >> n >> mod ){
        solve();
    }
    return 0;
}

版权声明:博主表示授权一切转载:)

时间: 2024-10-23 04:18:33

HDU 2256 Problem of Precision(矩阵快速幂)+ HDU 4565的相关文章

HDU 2256 Problem of Precision (矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2256 最重要的是构建递推式,下面的图是盗来的.貌似这种叫共轭数. 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 const int mod

HDU 2256 Problem of Precision 矩阵快速幂 + 共轭数

题意:中文不解释 解题思路: 中间矩阵为 5    2 12  5 初始矩阵为 2(根号b的系数) 5(a的系数) 解题代码: 1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<queue> 7 using namespace std; 8 int mod; 9 v

HDU 2256 Problem of Precision (矩阵快速幂)

HDU 2256 Problem of Precision (矩阵快速幂) ACM 题目地址:HDU 2256 Problem of Precision 题意: 给出一个式子,求值. 分析: 推起来最后那步会比较难想. 具体过程见: 表示共轭只听说过复数的和图的... 这构题痕迹好明显... 跟基友开玩笑说:如果遇到这种题,推到Xn+Yn*sqrt(6)这步时,打表最多只能打到10就爆int了,这是输出正解和Xn,说不定眼神好能发现ans = Xn * 2 - 1呢.= =... 代码: /*

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

hdu 1588 Gauss Fibonacci(矩阵快速幂)

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

HDU 4896 Minimal Spanning Tree(矩阵快速幂)

题意: 给你一幅这样子生成的图,求最小生成树的边权和. 思路:对于i >= 6的点连回去的5条边,打表知907^53 mod 2333333 = 1,所以x的循环节长度为54,所以9个点为一个循环,接下来的9个点连回去的边都是一样的.预处理出5个点的所有连通状态,总共只有52种,然后对于新增加一个点和前面点的连边状态可以处理出所有状态的转移.然后转移矩阵可以处理出来了,快速幂一下就可以了,对于普通的矩阵乘法是sigma( a(i, k) * b(k, j) ) (1<=k<=N), 现在

hdu 4965 Fast Matrix Calculation(矩阵快速幂)

题目链接:hdu 4965 Fast Matrix Calculation 题目大意:给定两个矩阵A,B,分别为N*K和K*N: 矩阵C = A*B 矩阵M=CN?N 将矩阵M中的所有元素取模6,得到新矩阵M' 计算矩阵M'中所有元素的和 解题思路:因为矩阵C为N*N的矩阵,N最大为1000,就算用快速幂也超时,但是因为C = A*B, 所以CN?N=ABAB-AB=AC′N?N?1B,C' = B*A, 为K*K的矩阵,K最大为6,完全可以接受. #include <cstdio> #inc

HDU 2294 Pendant (DP+矩阵快速幂降维)

HDU 2294 Pendant (DP+矩阵快速幂降维) ACM 题目地址:HDU 2294 Pendant 题意: 土豪给妹子做首饰,他有K种珍珠,每种N个,为了炫富,他每种珍珠都要用上.问他能做几种长度[1,N]的首饰. 分析: 1 ≤ N ≤ 1,000,000,000简直可怕. 首先想dp,很明显可以想到: dp[i][j] = (k-(j-1))*dp[i-1][j-1] + j*dp[i-1][j](dp[i][j]表示长度为i的并且有j种珍珠的垂饰有多少个) 然后遇到N太大的话,

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

HDU 1588 Gauss Fibonacci(矩阵快速幂+二分等比序列求和) ACM 题目地址:HDU 1588 Gauss Fibonacci 题意: g(i)=k*i+b;i为变量. 给出k,b,n,M,问( f(g(0)) + f(g(1)) + ... + f(g(n)) ) % M的值. 分析: 把斐波那契的矩阵带进去,会发现这个是个等比序列. 推倒: S(g(i)) = F(b) + F(b+k) + F(b+2k) + .... + F(b+nk) // 设 A = {1,1,

HDU 4965 Fast Matrix Calculation (矩阵快速幂取模----矩阵相乘满足结合律)

http://acm.hdu.edu.cn/showproblem.php?pid=4965 利用相乘的可结合性先算B*A,得到6*6的矩阵,利用矩阵快速幂取模即可水过. 1 #include<iostream> 2 #include<stdio.h> 3 #include<iostream> 4 #include<stdio.h> 5 #define N 1010 6 #define M 1010 7 #define K 6 8 using namespa