HDU---4565 So Easy!2012长沙邀请赛A题(共轭构造+矩阵的快速幂)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37868325/article/details/88846373

题意:

  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

思路:这个题感觉还是很有趣的。

假设\left ( a+\sqrt{b}\right )^{i}=x_{i}+y_{i}*\sqrt{b},

\left ( a+\sqrt{b}\right )^{n}=\left ( a+\sqrt{b}\right )^{n-1}*( a+\sqrt{b})

=(x_{n-1}+y_{n-1}*\sqrt{b})*(a+\sqrt{b})

=(a*x_{n-1}+b*y_{n-1})+(x_{n-1}+a*y_{n-1})\sqrt{b}

既可得x_{i}=(a*x_{i-1}+b*y_{i-1}),y_{i}=(x_{i-1}+a*y_{i-1})

转移矩阵为\begin{pmatrix} x_{n}\\ y_{n} \end{pmatrix} =\begin{pmatrix} a &b \\ 1& a \end{pmatrix}^{n}\begin{pmatrix} 1\\ 0 \end{pmatrix}

PS:注意用long long!!

通过给的数据信息,\left ( a-1 \right )^{2}<b<a^{2},就能知道,肯定跟解题有什么不可描述的关系。。(当然我没有推出来,是看了题解。)所以a-1<\sqrt{b}<a.所以0<\left ( a-\sqrt{b}\right )^{n}<1.

假设\left ( a+\sqrt{b}\right )^{n}=x+y*\sqrt{b}.那么\left ( a-\sqrt{b}\right )^{n}=x-y*\sqrt{b}.

\left ( a+\sqrt{b}\right )^{n}+\left ( a-\sqrt{b}\right )^{n}=2*x.因为是向上取整,所以\left \lceil \left ( a+\sqrt{b}\right )^{n} \right \rceil=2*x。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 10
//#define mod 6
ll n,mod,a,b;
///n行m列的矩阵
struct AA
{
    ll n,m,a[maxn][maxn];
    void mem1()
    {
        memset(a,0,sizeof(a));///n=m时,初始化为单位阵
        for(int i=0;i<n;i++)
            a[i][i]=1;
    }
};

///n行m列的aa矩阵 * m行k列的bb矩阵
AA mul(AA aa,AA bb,int n,int m,int k)
{
    AA cc;
    cc.n=n;cc.m=k;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<k;j++)
        {
            int x=0;
            for(int k=0;k<m;k++)
            {
                x+=aa.a[i][k]*bb.a[k][j]%mod;
                x%=mod;
            }
            cc.a[i][j]=x;
        }
    }
    return cc;
}

///方阵aa的m次方
AA POW(AA aa,int m)
{
    AA d;d.n=d.m=aa.n;
    d.mem1();
    while(m)
    {
        if(m&1)
        {
            d=mul(d,aa,d.n,d.m,aa.m);
        }
        m/=2;
        aa=mul(aa,aa,aa.n,aa.n,aa.n);
    }
    return d;
}
int main()
{
    while(~scanf("%lld%lld%lld%lld",&a,&b,&n,&mod))
    {
        AA aa,bb;aa.n=2;aa.m=2;bb.n=2;bb.m=1;
        bb.a[0][0]=1;
        bb.a[1][0]=0;
        aa.a[0][0]=a;
        aa.a[0][1]=b;
        aa.a[1][0]=1;
        aa.a[1][1]=a;
        AA cc=mul(POW(aa,n),bb,2,2,2);
        printf("%lld\n",cc.a[0][0]*2%mod);
    }
}
 
 

猜你喜欢

转载自blog.csdn.net/qq_37868325/article/details/88846373
so
SO?
今日推荐