题目链接 Broken Clock 中文题面链接
令$cos(xα) = f(x)$
根据三角函数变换公式有
$f(x) = frac{2d}{l} f(x-1) - f(x-2)$
我们现在要求的是$l * f(t)$,把$f(t)$表示成$frac{p}{q}$的形式
令$f(x) = frac{g(x)}{l^{x}}$,那么$g(x) = p, l^{x} = q$
$frac{g(x)}{l^{x}} = frac{2d}{l} * frac{g(x-1)}{l^{x-1}} - frac{g(x-2)}{l^{x-2}}$
$g(x) = 2dg(x-1) - l^{2}g(x-2)$
那么这就是一个很显然的矩阵加速的套路,用矩阵快速幂求解$g(t)$即可。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) #define MP make_pair #define fi first #define se second typedef long long LL; const LL mod = 1e9 + 7; struct Matrix{ LL arr[3][3]; } unit, a, c; LL p, q, d, l, t; int T, n; inline LL Pow(LL a, LL b, LL mod){ LL ret(1); for (; b; b >>= 1, (a *= a) %= mod) if (b & 1) (ret *= a) %= mod; return ret; } Matrix Mul(Matrix a, Matrix b){ Matrix c; rep(i, 1, n) rep(j, 1, n){ c.arr[i][j] = 0; rep(k, 1, n) (c.arr[i][j] += (a.arr[i][k] * b.arr[k][j] % mod)) %= mod; } return c; } Matrix Pow(Matrix a, int k){ Matrix ret(unit); for (; k; k >>= 1, a = Mul(a, a)) if (k & 1) ret = Mul(ret, a); return ret; } int main(){ n = 2; unit.arr[1][1] = unit.arr[2][2] = 1; scanf("%d", &T); while (T--){ scanf("%lld%lld%lld", &l, &d, &t); q = Pow(l, t, mod); c.arr[1][1] = 2 * d % mod; c.arr[1][2] = -l * l % mod; c.arr[1][2] += mod; c.arr[1][2] %= mod; c.arr[2][1] = 1; c.arr[2][2] = 0; --t; a = unit; while (t){ if (t & 1) a = Mul(a, c); t >>= 1; c = Mul(c, c); } p = (a.arr[1][1] * d % mod + a.arr[1][2] % mod) % mod; p %= mod; printf("%lld ", l * p % mod * Pow(q, mod - 2, mod) % mod); } return 0; }