2018.08.30【校内模拟】T2 k—斐波那契 (矩阵快速幂)(扩展欧几里得)(逆元)

版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/82221111

【描述】

这里写图片描述

【输入】

一行两个整数 n P

【输出】

从小到大输出可能的 k,若不存在,输出 None

【样例输入】

5 5

【样例输出】

2

【样例解释】

f[0] = 2
f[1] = 2
f[2] = 4
f[3] = 6 mod 5 = 1
f[4] = 5 mod 5 = 0
f[5] = 1

【数据规模与约定】

30%的数据保证 n, P ≤ 1000
100%的数据保证 n, P ≤ 10^9


解析:

组合数学和数论的结合。。。
今天不想写详解。。。
心态有点崩。。。


代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
#define st static

inline
ll getint(){
    re ll num=0;
    re char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);c=gc())num=(num<<1)+(num<<3)+(c^48);
    return  num;
}

inline
void outint(ll a){
    st char ch[23];
    if(a==0)pc('0');
    while(a)ch[++ch[0]]=(a-a/10*10)^48,a/=10;
    while(ch[0])pc(ch[ch[0]--]);
}

inline
ll gcd(ll a,ll b){
    return b?gcd(b,a-a/b*b):a;
}

inline
bool extend_gcd(ll a,ll b,ll &x,ll &y){
    if(b==0){
        x=1;
        y=0;
        return a!=1;
    }
    bool res=extend_gcd(b,a-a/b*b,y,x);
    y-=(ll)(a/b)*x;
    return res;
}

ll n,p;

struct matrix{
    ll t[2][2];
    matrix(){
        t[0][0]=t[1][1]=1;
        t[1][0]=t[0][1]=0;
    }
    friend matrix operator*(cs matrix &a,cs matrix &b){
        matrix c;
        c.t[0][0]=(a.t[0][0]*b.t[0][0]+a.t[0][1]*b.t[1][0])%p;
        c.t[1][1]=(a.t[1][0]*b.t[0][1]+a.t[1][1]*b.t[1][1])%p;
        c.t[1][0]=(a.t[1][0]*b.t[0][0]+a.t[1][1]*b.t[1][0])%p;
        c.t[0][1]=(a.t[0][0]*b.t[0][1]+a.t[0][1]*b.t[1][1])%p;
        return c;
    }
};

matrix quickpow(matrix a,int b){
    matrix res;
    res=matrix();
    while(b){
        if(b&1)res=res*a;
        b>>=1;
        a=a*a;
    }
    return res;
}

int main(){
    n=getint();
    p=getint();
    if(p==1||p==0){
        puts("None");
        return 0;
    }
    matrix ans,tmp;
    tmp.t[0][0]=0;
    tmp.t[1][0]=1;
    tmp.t[1][1]=1;
    tmp.t[0][1]=1;
    ans=quickpow(tmp,n);
    ll kk=ans.t[0][0]+ans.t[1][0];
    kk%=p;
    ll x,y;
    if(extend_gcd(kk,p,x,y)){
        puts("None");
    }
    else cout<<(x%p+p)%p;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zxyoi_dreamer/article/details/82221111