UVA 10655 Contemplation! Algebra(矩阵快速幂)

Given the value of a+b and ab you will have to find the value of an+bn

Input

The input file contains several lines of inputs. Each line except the last line contains 3 non-negative integers pq and n. Here p denotes the value of a+b andq denotes
the value of ab. Input is terminated by a line containing only two zeroes. This line should not be processed. Each number in the input file fits in a signed 32-bit integer. There will be no such input so that you have to find
the value of 00.

Output

For each line of input except the last one produce one line of output. This line contains the value of an+bn.  You can always assume that an+bfits in a signed 64-bit integer.

Sample Input                               Output for Sample Input

10 16 2 
7 12 3 
0 0

68

91 


Problem setter: Shahriar Manzoor, Member of Elite Problemsetters‘ Panel

Special Thanks: Mohammad Sajjad Hossain

题意很明显就是求a^n+b^n;

我们发现f0=2,f1=a+b,f2=a^2+b^2=(a+b)*f1-a*b*f2....

依次递推,令p=a+b,q=a*b;

所以fi=fi-1*p-fi-2*q;

构造出矩阵后就可以求解了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef long long LL;
typedef pair<int,int>pil;
const int INF = 0x3f3f3f3f;
struct Matrix{
    LL mat[2][2];
    void Clear()
    {
        CLEAR(mat,0);
    }
};
Matrix mult(Matrix m1,Matrix m2)
{
    Matrix ans;
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
        {
            ans.mat[i][j]=0;
            for(int k=0;k<2;k++)
                ans.mat[i][j]=ans.mat[i][j]+m1.mat[i][k]*m2.mat[k][j];
        }
    return ans;
}
Matrix Pow(Matrix m1,LL b)
{
    Matrix ans;ans.Clear();
    for(int i=0;i<2;i++)
        ans.mat[i][i]=1;
    while(b)
    {
        if(b&1)
           ans=mult(ans,m1);
        b>>=1;
        m1=mult(m1,m1);
    }
    return ans;
}
LL p,q,n;
int main()
{
    while(scanf("%lld%lld%lld",&p,&q,&n)==3)
    {
        Matrix A;
        if(n==0)
        {
            puts("2");
            continue;
        }
        if(n==1)
        {
            printf("%lld\n",p);
            continue;
        }
        A.mat[0][0]=p;A.mat[0][1]=-q;
        A.mat[1][0]=1;A.mat[1][1]=0;
        A=Pow(A,n-1);
        LL ans=A.mat[0][0]*p+A.mat[0][1]*2;
        printf("%lld\n",ans);
    }
    return 0;
}

HDU 4565

So Easy!

Problem Description

  A sequence Sn is defined as:

Where a, b, n, m are positive integers.┌x┐is the ceil of x. For example, ┌3.14┐=4. You are to calculate Sn.

  You, a top coder, say: So easy!

Input

  There are several test cases, each test case in one line contains four positive integers: a, b, n, m. Where 0< a, m < 215, (a-1)2< b < a2, 0 < b, n < 231.The input will finish with the end of file.

Output

  For each the case, output an integer Sn.

Sample Input

2 3 1 2013
2 3 2 2013
2 2 1 2013

Sample Output

4
14
4

题目要求这个式子答案,我们发现(a-1)^2<b<a^2这就意味着a-1<sqrt(b)<a;

所以又(a+sqrt(b))^n+(a-sqrt(b))^n为整数,所以式子答案即为(a+sqrt(b))^n+(a-sqrt(b))^n

简化下,就是上面的a‘=a+sqrt(b),b‘=a-sqrt(b);所以p=2*a,q=a*a-b;

问题转化为上题做法。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef long long LL;
typedef pair<int,int>pil;
const int INF = 0x3f3f3f3f;
struct Matrix{
    LL mat[2][2];
    void Clear()
    {
        CLEAR(mat,0);
    }
};
LL a,b,n,m;
Matrix mult(Matrix m1,Matrix m2)
{
    Matrix ans;
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
        {
            ans.mat[i][j]=0;
            for(int k=0;k<2;k++)
                ans.mat[i][j]=(ans.mat[i][j]+m1.mat[i][k]*m2.mat[k][j])%m;
        }
    return ans;
}
Matrix Pow(Matrix m1,LL b)
{
    Matrix ans;ans.Clear();
    for(int i=0;i<2;i++)
        ans.mat[i][i]=1;
    while(b)
    {
        if(b&1)
            ans=mult(ans,m1);
        b>>=1;
        m1=mult(m1,m1);
    }
    return ans;

}
int main()
{
    while(scanf("%I64d%I64d%I64d%I64d",&a,&b,&n,&m)!=EOF)
    {
        LL p=2*a,q=a*a-b;//x^n+y^n
        Matrix A;
        if(n==1)
        {
            printf("%I64d\n",p);
            continue;
        }
        A.mat[0][0]=p;A.mat[0][1]=-q;
        A.mat[1][0]=1;A.mat[1][1]=0;
        A=Pow(A,n-1);
        LL ans=A.mat[0][0]*p%m;
        ans=((ans+A.mat[0][1]*2)%m+m)%m;
        printf("%I64d\n",ans);
    }
    return 0;
}
时间: 2024-10-11 08:39:19

UVA 10655 Contemplation! Algebra(矩阵快速幂)的相关文章

UVA 10655 - Contemplation! Algebra(矩阵快速幂)

UVA 10655 - Contemplation! Algebra 题目链接 题意:给定p, q, n代表p=a+b,q=ab求an+bn 思路:矩阵快速幂,公式变换一下得到(an+bn)(a+b)=an+1+bn+1+ab(an?1+bn?1),移项一下得到an+1+bn+1=(an+bn)p?q(an?1+bn?1) 这样就可以用矩阵快速幂求解了 代码: #include <stdio.h> #include <string.h> long long p, q, n; str

Contemplation! Algebra 矩阵快速幂

Given the value of a+b and ab you will have to find the value of a n + b n Input The input file contains several lines of inputs. Each line except the last line contains 3 non-negative integers p, q and n. Here p denotes the value of a+b and q denote

Contemplation! Algebra(矩阵快速幂,uva10655)

Problem EContemplation! AlgebraInput: Standard Input Output: Standard Output Time Limit: 1 Second Given the value of a+b and ab you will have to find the value of an+bn Input The input file contains several lines of inputs. Each line except the last

Uva 11551 - Experienced Endeavour ( 矩阵快速幂 )

Uva 11551 - Experienced Endeavour ( 矩阵快速幂 ) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAX_SIZE 50 #define MOD 1000 #define CLR( a, b ) memset( a, b, sizeof(a) ) struct Mat { int n; int mat[MAX

UVA 10655 Contemplation! Algebra (矩阵快速幂)

题目链接:传送门 题意: 给定你三个数,p,q,n, p代表的是 a + b, q代表的是a*b; 然后求a^n + b^n 设f[i] = a^i +b^i; f[0]=2,f[1]=p; f[i]*(a+b) = a^(i+1) + b^(i+1) +a^i*b + b^i*a; f[i]*p = f[i+1] + a*b*[ a^(i-1) + b^(i-1) ] f[i+1] = f[i]*p + q*f[i-1]; 然后用矩阵加速一下就可以了(ps.这个题的输入非常坑....) 代码如

UVA 10655 Contemplation! Algebra

Given the value of a+b and ab you will have to find the value of an+bn Input The input file contains several lines of inputs. Each line except the last line contains 3 non-negative integers p, q and n. Here p denotes the value of a+b and q denotes th

UVA - 10229 - Modular Fibonacci (矩阵快速幂 + fibonacci)

题目传送:UVA - 10229 思路:就是简单的矩阵快速幂求fibonacci数列,然后注意可能中间结果会爆int,因为2^19有50多万 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include <stack> #includ

uva 11651 - Krypton Number System(矩阵快速幂)

题目链接:uva 11651 - Krypton Number System 题目大意:给定进制base,和分数score,求在base进制下,有多少个数的值为score,要求不能有连续相同的数字以及前导0.计算一个数的值即为相邻两位数的平方差和. 解题思路:因为score很大,所以直接dp肯定超时,但是即使对于base=6的情况,每次新添一个数score最大增加25(0-5),所以用dp[i][j]预处理出base平方以内的总数,然后用矩阵快速幂计算. #include <cstdio> #

UVA 11651 - Krypton Number System(DP+矩阵快速幂)

UVA 11651 - Krypton Number System 题目链接 题意:给一个进制base,一个分数score求该进制下,有多少数满足一下条件: 1.没有连续数字 2.没有前导零 3.分数为score,分数的计算方式为相邻数字的平方差的和 思路:先从dp入手,dp[i][j]表示组成i,最后一个数字为j的种数,然后进行状态转移,推出前面一步能构成的状态,也就是到dp[(b - 1) * (b - 1)][x]. 然后可以发现后面的状态,都可以由前面这些状态统一转移出来,这样就可以利用