Luogu P3263 [JLOI2015]意味のある文字列

リンク
設定\(E = \ {FRAC B + \ SQRT D 2}、Iは{FRAC B- \ SQRT 2} D \ \ =)
明らかに\(f_n = E + I ^ N \ ^ n)の整数であり、\(F_n =(E + I)。1-N-F_ {+} 2-N- eif_ {} \)
再発(E = B + I、EI = \ FRAC B ^ {2}。4-D \)\、タイトルに応じて、これら2つの条件は整数です。
私たちは、マトリックスの電源を使用することができますので、すぐに見つける(F_n \ BMOD P \)\
明らかに\(I \で(-1,0] \) そう\(N-I ^ \で(-1,0] \) そう\(\ lfloor E ^ nは\ rfloor \当量f_n- \ lceil | I N- ^ | \ rceil \ PMOD P \) 直接測定することができます。

#include<cstdio>
#include<cstring>
using u64=unsigned long long;
const u64 P=7528443412579576937ll;
u64 inc(u64 a,u64 b){return a+=b,a>=P? a-P:a;}
u64 mul(u64 a,u64 b){u64 r=0;for(;b;b>>=1,a=inc(a,a))if(b&1)r=inc(a,r);return r;}
struct matrix{u64 a[3][3];matrix(){memset(a,0,72);}u64*operator[](int x){return a[x];}}E,I;
matrix operator*(matrix a,matrix b)
{
    matrix c;
    for(int i=1;i<=2;++i) for(int j=1;j<=2;++j) for(int k=1;k<=2;++k) c[i][j]=inc(c[i][j],mul(a[i][k],b[k][j]));
    return c;
}
int main()
{
    u64 b,d,n;int f;
    scanf("%llu%llu%llu",&b,&d,&n);
    if(!n) return !printf("1");
    f=--n&1,E[1][2]=(d-b*b)/4,E[2][1]=1,E[2][2]=b,I[1][1]=I[2][2]=1;
    for(;n;n>>=1,E=E*E) if(n&1) I=E*I;
    printf("%llu",inc(mul(2,I[1][2]),mul(b,I[2][2]))-(d*d^b&&f));
}

おすすめ

転載: www.cnblogs.com/cjoierShiina-Mashiro/p/12375006.html