CSU - 1895——Apache is late again ( (1 + sqrt (2)) ^ n = sqrt (m) + sqrt (m-1) 求m)

Apache is a student of CSU. There is a math class every Sunday morning, but he is a very hard man who learns late every night. Unfortunate, he was late for maths on Monday. Last week the math teacher gave a question to let him answer as a punishment, but he was easily resolved. So the math teacher prepared a problem for him to solve. Although Apache is very smart, but also was stumped. So he wants to ask you to solve the problem. Questions are as follows: You can find a m made (1 + sqrt (2)) ^ n can be decomposed into sqrt (m) + sqrt (m-1), if you can output m% 100,000,007 otherwise output No.

Input

There are multiply cases. Each case is a line of n. (|n| <= 10 ^ 18)

Output

Line, if there is no such m output No, otherwise output m% 100,000,007.

Sample Input
2
Sample Output
 
 

9


#include<algorithm>
#include<string.h>
#include<stdio.h>
#define LL long long
#define mod 100000007
using namespace std;
struct node
{
    LL v[5][5];
    node()
    {
        memset(v,0,sizeof(v));
    }
    node operator * (const node &m)
    {
        node c;
        for(int i=1; i<=2; i++)
        {
            for(int j=1; j<=2; j++)
            {
                c.v[i][j]=0;
                for(int k=1; k<=2; k++)
                {
                    c.v[i][j] += (v[i][k] * m.v[k][j]) % mod;
                    c.v[i][j]%=mod;
                }
            }
        }
        return c;
    }
};
void init(node &a,node &b)
{
    for(int i=1; i<=2; i++)
    {
        b.v[i][i]=1;
    }
    b.v[1][2]=0;
    b.v[2][1]=0;
    a.v[1][1]=2;
    a.v[1][2]=1;
    a.v[2][1]=1;
    a.v[2][2]=0;
}
node ksm(node a,node b,LL k)
{
    while(k)
    {
        if(k&1)
        {
            b=a*b;
        }
        k/=2;
        a=a*a;
    }
    return b;
}
int main()
{
    node a,b,c;
    LL n,m;
    while(~scanf("%lld",&n))
    {
        if(n<0)
        {
            printf("No\n");
            continue;
        }
        init(a,b);
        switch(n)
        {
        case 0:
        {
            printf("1\n");
            break;
        }
        case 1:
        {
            printf("2\n");
            break;
        }
        case 2:
        {
            printf("9\n");
            break;
        }
        default:
        {
            c=ksm(a,b,n-2);
            m=(3*c.v[1][1]+c.v[1][2])%mod;
            if(n&1)
            {
                m=(m*m+1)%mod;
            }
            else
                m=(m*m)%mod;
            printf("%lld\n",m);
        }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_41380961/article/details/80387951
今日推荐