首先我们发现$\frac{b+\sqrt{d}}{2}$这个形式好像一元二次方程的求根公式啊(???反正我发现不了)
然后我们又想到虽然这个东西不好求但是$(\frac{b-\sqrt{d}}{2})^n$好像挺好求的啊(???反正我想不到)(由题目给的范围,这玩意在(-1,1))
于是把这个方程写出来:$x^2-b+\frac{b^2-d}{4}=0$,设它的两根是$x_1=\frac{b+\sqrt{d}}{2} , x_2=\frac{b-\sqrt{d}}{2}$
于是就是要求$\lfloor x_1^n+x_2^n-x_2^n \rfloor$
我们把$x_1^n+x_2^n$单拎出来,分解一下,得到$x_1^n+x_2^n = (x_1+x_2)(x_1^{n-1}+x_2^{n-1}) - x_1x_2(x_1^{n-2}+x_2^{n-2}) $
然后$x_1+x_2$和$x_1x_2$可以用韦达定理算,再把$x_1^i+x_2^i$设成f[i],就可以用矩阵快速幂优化了
可以发现它是个整数,最后讨论一下$x_2^n$就行了
(模数巨大,不光要用龟速乘,还要用unsigned long long)
1 #include2 #define CLR(a,x) memset(a,x,sizeof(a)) 3 using namespace std; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 typedef pair pa; 7 const ull P=7528443412579576937; 8 9 inline ll rd(){10 ll x=0;char c=getchar();int neg=1;11 while(c<'0'||c>'9'){ if(c=='-') neg=-1;c=getchar();}12 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();13 return x*neg;14 }15 16 ull fmul(ull a,ull b){17 ull re=0;18 while(b){19 if(b&1) re=(re+a)%P;20 a=(a+a)%P,b>>=1;21 }return re;22 }23 24 ull b,d,n;25 26 ull fpow(ull x){27 ull f[2];f[0]=b,f[1]=2;28 ull m[2][2],tmp[2][2];29 m[0][0]=b,m[0][1]=1,m[1][0]=(d-b*b)/4,m[1][1]=0;30 while(x){31 if(x&1){32 CLR(tmp,0);33 for(int i=0;i<=1;i++){34 for(int j=0;j<=1;j++){35 tmp[0][i]=(tmp[0][i]+fmul(f[j],m[j][i]))%P;36 }37 }38 f[0]=tmp[0][0],f[1]=tmp[0][1];39 }40 CLR(tmp,0);41 for(int i=0;i<=1;i++){42 for(int j=0;j<=1;j++){43 for(int k=0;k<=1;k++){44 tmp[i][j]=(tmp[i][j]+fmul(m[i][k],m[k][j]))%P;45 }46 }47 }48 memcpy(m,tmp,sizeof(m));49 x>>=1;50 }return f[0];51 }52 53 int main(){54 //freopen("","r",stdin);55 int i,j,k;56 b=rd(),d=rd(),n=rd();57 if(n==0) printf("1\n");58 else{59 ull ans=fpow(n-1);60 if(!(n&1)&&d!=b*b) ans=(P+ans-1)%P;61 printf("%lld\n",ans);62 }63 64 return 0;65 }