题目链接 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\n", l * p % mod * Pow(q, mod - 2, mod) % mod);
}
return 0;
}