给定正整数
b,d,n
,求
⌊(b+d‾√2)n⌋mod7528443412579576937
其中 0<b2≤d<(b+1)2≤1018,n≤1018,bmod2=1,dmod4=1
二项线性递推数列的通项公式是
xn=C1rn+C2sn
递推公式是:
xn=uxn−1+vxn−2
其中 r,s 是数列特征方程 y2=uy+v 的两根。
而且该特征方程两根是
y=u±u2+4v‾‾‾‾‾‾‾√2
即
y=A±B‾‾√2
又题目给定的是 b+d√2 ,所以另一根就是 b−d√2
由 b,d 的条件 b2≤d<(b+1)2 知
b−d‾√2∈(−12,0]
同时比对特征方程根式可知:
u=b,v=d−b24
递推公式得:
xn+2=bxn+1+d−b24xn
且 bmod2=1,dmod4=1 ,故 v 为正整数。则
同时:
xn=(b+d‾√2)n+(b−d‾√2)n
∴(b+d‾√2)n=xn−(b−d‾√2)n
而 xn 的值可以通过矩阵乘法快速求得。
至于 h(n)=(b−d√2)n ,当且仅当 b≠d‾√ 且 n 为偶数时
3个0ms是怎么写的。。为了上第一页真是豁出去了233。
#include <cstdio>
#define rep(i,j,k) for(int i=j;i<k;i++)
typedef unsigned long long ull;
const ull MOD = 7528443412579576937ll;
inline void add(ull &a, ull b) { a += b; if (a > MOD) a -= MOD; }
inline ull mul(ull a, ull b) {
ull x = 0; for (; b; add(a, a), b >>= 1) if(b & 1) add(x, a); return x;
}
struct Matrix {
ull c[2][2];
Matrix(int x = 0) { c[0][1] = c[1][0] = 0; rep(i,0,2) c[i][i] = x; }
Matrix operator * (const Matrix& a) const {
Matrix z;
rep(i,0,2) rep(j,0,2) rep(k,0,2) z.c[i][j] = (z.c[i][j] + mul(c[i][k], a.c[k][j])) % MOD;
return z;
}
friend Matrix operator ^(Matrix a, ull p) {
Matrix v(1); for (; p; a = a * a, p >>= 1) if(p & 1) v = a * v; return v;
}
} a;
int main() {
long long b, d, n, ans;
scanf("%lld%lld%lld", &b, &d, &n);
if (n == 0) ans = 1;
else {
a.c[0][0] = b; a.c[0][1] = d - b * b >> 2; a.c[1][0] = 1;
a = a ^ (n - 1); ans = (mul(a.c[0][0], b) + mul(a.c[0][1], 2)) % MOD;
if (d != b * b && n % 2 == 0) ans -= 1;
}
return printf("%lld\n", ans), 0;
}