题意:求
⌊
(
b
+
d
2
)
n
⌋
m
o
d
7528443412579576937
\lfloor(\frac{b+\sqrt{d}}{2})^n\rfloor\ mod\ 7528443412579576937
⌊(2b+d)n⌋ mod 7528443412579576937的值。
题解:get到了好多的新姿势qwq。
首先get到了特征多项式相关姿势。orz zjr and yeh dark♂佬,直接秒了特征多项式。
我们设有一个数列
x
x
x,满足
x
n
+
2
=
c
1
x
n
+
1
+
c
2
x
n
x_{n+2}=c_{1}x_{n+1}+c_{2}x_{n}
xn+2=c1xn+1+c2xn。
我们设存在
r
r
r,
s
s
s,满足
x
n
+
2
−
r
x
n
+
1
=
s
(
x
n
+
1
−
r
x
n
)
x_{n+2}-rx_{n+1}=s(x_{n+1}-rx_{n})
xn+2−rxn+1=s(xn+1−rxn)。
移项得
x
n
+
2
=
(
s
+
r
)
x
n
+
1
−
s
r
×
x
n
x_{n+2}=(s+r)x_{n+1}-sr\times x_{n}
xn+2=(s+r)xn+1−sr×xn
可以得到
c
1
=
s
+
r
(
1
)
c_{1}=s+r\ (1)
c1=s+r (1),
c
2
=
−
s
r
(
2
)
c_{2}=-sr\ (2)
c2=−sr (2)。
我们让
(
1
)
×
r
+
(
2
)
(1)\times r+(2)
(1)×r+(2),得到
r
c
1
+
c
2
=
r
2
rc_{1}+c_{2}=r^2
rc1+c2=r2
这就是一个一元二次方程,可以直接解出。
我们设这个方程的两个根为
p
,
q
p,q
p,q。
存在
A
,
B
A,B
A,B使得
x
n
=
A
×
p
n
+
B
×
q
n
x_{n}=A\times p^{n}+B\times q^{n}
xn=A×pn+B×qn。
只需要带入两个
n
n
n的值,就可以把
A
A
A和
B
B
B求出,也就是得出了通项公式。
我们现在要求的就是
(
b
+
d
2
)
n
(\frac{b+\sqrt{d}}{2})^n
(2b+d)n。
我们构造一个式子
(
(
b
+
d
2
)
n
+
(
b
−
d
2
)
n
)
−
(
b
−
d
2
)
n
((\frac{b+\sqrt{d}}{2})^n+(\frac{b-\sqrt{d}}{2})^n)-(\frac{b-\sqrt{d}}{2})^n
((2b+d)n+(2b−d)n)−(2b−d)n
前面这些东西
(
(
b
+
d
2
)
n
+
(
b
−
d
2
)
n
)
((\frac{b+\sqrt{d}}{2})^n+(\frac{b-\sqrt{d}}{2})^n)
((2b+d)n+(2b−d)n),我们可以把这个看成一个递推式的通项,得到
A
=
1
,
B
=
1
,
p
=
b
+
d
2
,
q
=
b
−
d
2
A=1,B=1,p=\frac{b+\sqrt{d}}{2},q=\frac{b-\sqrt{d}}{2}
A=1,B=1,p=2b+d,q=2b−d。所以现在我们要做的就是由通项求出递推式。
因为
p
,
q
p,q
p,q是方程
r
c
1
+
c
2
=
r
2
rc_{1}+c_{2}=r^2
rc1+c2=r2的两个根,我们可以尝试把他们带入,得到
(
b
+
d
2
)
2
=
c
1
×
(
b
+
d
2
)
+
c
2
(3)
(\frac{b+\sqrt d}{2})^2=c_{1}\times(\frac{b+\sqrt d}{2})+c_{2}\tag{3}
(2b+d)2=c1×(2b+d)+c2(3)
(
b
−
d
2
)
2
=
c
1
×
(
b
−
d
2
)
+
c
2
(4)
(\frac{b-\sqrt d}{2})^2=c_{1}\times(\frac{b-\sqrt d}{2})+c_{2}\tag{4}
(2b−d)2=c1×(2b−d)+c2(4)
化简得
b
2
+
2
b
d
+
d
4
=
c
1
b
+
c
1
d
2
+
c
2
(5)
\frac{b^2+2b\sqrt d+d}{4}=\frac{c_{1}b+c_{1}\sqrt d}{2}+c_{2}\tag{5}
4b2+2bd+d=2c1b+c1d+c2(5)
b
2
−
2
b
d
+
d
4
=
c
1
b
−
c
1
d
2
+
c
2
(6)
\frac{b^2-2b\sqrt d+d}{4}=\frac{c_{1}b-c_{1}\sqrt d}{2}+c_{2}\tag{6}
4b2−2bd+d=2c1b−c1d+c2(6)
(
3
)
+
(
4
)
(3)+(4)
(3)+(4)得
b
2
+
d
2
=
c
1
b
+
2
c
2
(7)
\frac{b^2+d}{2}=c_{1}b+2c_{2}\tag{7}
2b2+d=c1b+2c2(7)
(
3
)
−
(
4
)
(3)-(4)
(3)−(4)得
c
1
=
b
c_{1}=b
c1=b。带入
(
7
)
(7)
(7)得到
c
2
=
d
−
b
2
4
c_{2}=\frac{d-b^2}{4}
c2=4d−b2。
于是我们成功推出了递推式:
x
n
=
b
×
x
n
−
1
+
d
−
b
2
4
×
x
n
−
2
x_{n}=b\times x_{n-1}+\frac{d-b^2}{4}\times x_{n-2}
xn=b×xn−1+4d−b2×xn−2。
很容易得到边界
x
0
=
2
,
x
1
=
b
x_{0}=2,x_{1}=b
x0=2,x1=b。
注意到
b
≡
1
m
o
d
2
b\equiv1\ mod\ 2
b≡1 mod 2,
d
≡
1
m
o
d
4
d\equiv1\ mod\ 4
d≡1 mod 4,所以
(
b
+
d
2
)
n
+
(
b
−
d
2
)
n
(\frac{b+\sqrt{d}}{2})^n+(\frac{b-\sqrt{d}}{2})^n
(2b+d)n+(2b−d)n一定是整数。所以我们可以直接跑整数的矩阵乘法。
注意到
b
2
≤
d
<
(
b
+
1
)
2
b^2\leq d<(b+1)^2
b2≤d<(b+1)2,所以
(
b
−
d
2
)
n
(\frac{b-\sqrt{d}}{2})^n
(2b−d)n一定在
(
−
1
,
0
]
(-1,0]
(−1,0]内。
(
b
−
d
2
)
n
(\frac{b-\sqrt{d}}{2})^n
(2b−d)n对答案有影响,当且仅当
b
×
b
≠
d
b\times b\ne d
b×b=d且
n
n
n为偶数。这时答案要减1。
注意模数很恶心,一加都爆
l
o
n
g
l
o
n
g
long\ long
long long,不仅要用
O
(
1
)
O(1)
O(1)快速乘,还要用
u
n
s
i
g
n
e
d
l
o
n
g
l
o
n
g
unsigned\ long\ long
unsigned long long。
代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#define int unsigned long long
const int mod=7528443412579576937;
int b,d,n,k,a[2][2],base[2][2],tmp[2][2];
int mul(int a,int b){
long long c=a*(long double)b/mod+0.5;
long long res=a*b-c*mod;
if(res<0){
res+=mod;
}
return res;
}
int fastpow(int a,int x){
int res=1;
while(x){
if(x&1){
res=mul(res,a);
}
x>>=1;
a=mul(a,a);
}
return res;
}
void mul(int a[][2],int b[][2],int c[][2]){
memset(tmp,0,sizeof(tmp));
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
for(int k=0;k<2;k++){
tmp[i][j]=(tmp[i][j]+mul(a[i][k],b[k][j]))%mod;
}
}
}
memcpy(c,tmp,sizeof(tmp));
}
signed main(){
scanf("%lld%lld%lld",&b,&d,&n);
if(!n){
puts("1");
return 0;
}else if(n==1){
printf("%lld\n",(int)(0.5*(b+sqrt(d))));
return 0;
}
a[0][0]=2;
a[0][1]=b;
base[0][1]=(d-b*b)/4;
base[1][0]=1;
base[1][1]=b;
int k=n;
while(k){
if(k&1){
mul(a,base,a);
}
k>>=1;
mul(base,base,base);
}
if(n%2==0&&b*b!=d){
printf("%lld\n",a[0][0]-1);
}else{
printf("%lld\n",a[0][0]);
}
return 0;
}