hdu4565矩阵快速幂

这题太坑了。。。刚开始以为可以用|a+sqrt(b)  1|水过。。。结果tle,还一直想明明我logn的做法怎么可能tle。。

|    0           1|

实在无奈看的题解 (a+sqrt(b))^n=x+y*sqrt(b);  (a+sqrt(b))^(n+1)=a*x+b*y+(x+a*y)*sqrt(b)

这样可以构造矩阵|a  b|    *   |x|

|1  b|         |y|

还有记得矩阵乘法%m

最后还有一个坑就是

(a-1)^2<b<a^2 ,

0 < ( a - sqrt( b ) )^ n < 1

( a + sqrt( b ) )^ n + ( a - sqrt( b ) )^ n = 2 * Xn

( a + sqrt( b ) )^ n 向上取整的值就是 2 * Xn(不用会超时@[email protected])

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<iomanip>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pi acos(-1)
#define ll long long
#define mod 10
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

const double g=10.0,eps=1e-9;
const int N=10+5,maxn=1<<10+5,inf=0x3f3f3f3f;

struct Node{
    ll row,col;
    ll a[N][N];
};
ll m;
Node mul(Node x,Node y)
{
    Node ans;
    ans.row=x.row,ans.col=y.col;
    memset(ans.a,0,sizeof ans.a);
    for(ll i=0;i<x.row;i++)
        for(ll j=0;j<x.col;j++)
            for(ll k=0;k<y.col;k++)
                ans.a[i][k]=(ans.a[i][k]+x.a[i][j]*y.a[j][k])%m;
    return ans;
}
Node quick_mul(Node x,ll n)
{
    Node ans;
    ans.row=x.row,ans.col=x.col;
    memset(ans.a,0,sizeof ans.a);
    for(ll i=0;i<ans.col;i++)ans.a[i][i]=1;
    while(n){
        if(n&1)ans=mul(ans,x);
        x=mul(x,x);
        n>>=1;
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
 //   cout<<setiosflags(ios::fixed)<<setprecision(2);
    ll a,b,n;
    while(cin>>a>>b>>n>>m){
        Node A;
        A.row=2,A.col=2;
        A.a[0][0]=a,A.a[0][1]=b;
        A.a[1][0]=1,A.a[1][1]=a;
        A=quick_mul(A,n);
        ll ans=A.a[0][0]*2;
        cout<<ans%m<<endl;
    }
    return 0;
}

时间: 2024-11-26 02:44:29

hdu4565矩阵快速幂的相关文章

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

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

HDU2256&amp;&amp;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

hdu4565 So Easy!(矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4565 题解:(a+√b)^n=xn+yn*√b,(a-√b)^n=xn-yn*√b, (a+√b)^n=2*xn-(a-√b)^n,(0<=a-√b<=1),所以整数部分就是2*xn 然后再利用两个公式 (a+√b)^(n+1)=(a+√b)*(xn+yn*√b) (a-√b)^(n+1)=(a-√b)*(xn-yn*√b) 联立得到 x(n+1)=a*xn+b*yn y(n+1)=xn+a*yn

矩阵快速幂刷题系列

来源自http://blog.csdn.net/chenguolinblog/article/details/10309423 hdu 1575 Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5587    Accepted Submission(s): 4200 Problem Description A为一个方阵,则Tr

HDU 1757 A Simple Math Problem (矩阵快速幂)

[题目链接]:click here~~ [题目大意]: If x < 10 f(x) = x. If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + -- + a9 * f(x-10); 问f(k)%m的值. [思路]:矩阵快速幂,具体思路看代码吧,注意一些细节. 代码: #include<bits/stdc++.h> using namespace std; typedef long long LL; const

Codeforces Round #291 (Div. 2) E - Darth Vader and Tree (DP+矩阵快速幂)

这题想了好长时间,果断没思路..于是搜了一下题解.一看题解上的"快速幂"这俩字,不对..这仨字..犹如醍醐灌顶啊...因为x的范围是10^9,所以当时想的时候果断把dp递推这一方法抛弃了.我怎么就没想到矩阵快速幂呢.......还是太弱了..sad..100*100*100*log(10^9)的复杂度刚刚好. 于是,想到了矩阵快速幂后,一切就变得简单了.就可以把距离<=x的所有距离的点数都通过DP推出来,然后一个快速幂就解决了. 首先DP递推式很容易想到.递推代码如下: for(

POJ 3233 - Matrix Power Series ( 矩阵快速幂 + 二分)

POJ 3233 - Matrix Power Series ( 矩阵快速幂 + 二分) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; #define MAX_SIZE 30 #define CLR( a, b ) memset( a, b, sizeof(a) ) int MOD = 0; int n, k; st

HDU 4990 Reading comprehension(找规律+矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4990 Problem Description Read the program below carefully then answer the question. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include<iostream> #include

hdu 6198(矩阵快速幂)

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 175    Accepted Submission(s): 119 暴力发现当4 12 33 88 232 和斐波那契数列对比  答案为 第2*k+3个数减1 直接用矩阵快速幂求的F[2*k+3]  然后减1 A=1,B=0; 然后矩阵快速幂2*k