51NOD 1537 分解

来源:互联网 发布:中世纪2原版优化9血统 编辑:程序博客网 时间:2024/04/30 00:40

1537 分解
基准时间限制:0.5 秒 空间限制:131072 KB 分值: 80 难度:5级算法题

问(1+sqrt(2)) ^n 能否分解成 sqrt(m) +sqrt(m-1)的形式
如果可以 输出 m%1e9+7 否则 输出no

Input

一行,一个数n。(n<=10^18)

Output

一行,如果不存在m输出no,否则输出m%1e9+7

Input示例

2

Output示例

9


找奇偶性规律+快速幂
(1+sqrt(2) )^n 可以表示为x+y*sqrt(2)
打表发现

n为偶数时 m=x*xn为奇数时 m=x*x+1

显然 xn,yn满足

xn   =  1    2   *  x(n-1)yn      1    1      y(n-1)

矩阵快速幂

#include<iostream>#include<stdlib.h>#include<stdio.h>#include<string>#include<vector>#include<deque>#include<queue>#include<algorithm>#include<set>#include<map>#include<stack>#include<time.h>#include<math.h>#include<list>#include<cstring>#include<fstream>//#include<memory.h>using namespace std;#define ll long long#define ull unsigned long long#define pii pair<int,int>#define INF 1000000007#define pll pair<ll,ll>#define pid pair<int,double>void mult(ll res[2][2],ll x[2][2]){    ll t[2][2];    for(int i=0;i<2;++i)        for(int j=0;j<2;++j){            t[i][j]=0;            for(int k=0;k<2;++k)                t[i][j]=(t[i][j]+res[i][k]*x[k][j])%INF;        }    for(int i=0;i<2;++i)        for(int j=0;j<2;++j)            res[i][j]=t[i][j];}ll matrix_pow(ll n){    --n;    ll res[2][2]={{1,0},                   {0,1}};    ll x[2][2]={{1,2},                 {1,1}};    while(n){        if(n&1)            mult(res,x);        mult(x,x);        n>>=1;    }    return (res[0][0]+res[0][1])%INF;}int main(){    //freopen("/home/lu/文档/r.txt","r",stdin);    //freopen("/home/lu/文档/w.txt","w",stdout);    ll n;    scanf("%lld",&n);    ll x=matrix_pow(n);    cout<<((n&1)+x*x)%INF<<endl;    return 0;}
0 0
原创粉丝点击