题目
思路
在斐波那契数列的基础上进行推导,可以推出式子。
用二次剩余定理处理左侧的根号五,右边用 欧拉降幂 + 快速幂 + 逆元 等数论知识处理一下即可。
可以提前算的最好提前算一下,这道题很卡常。
出题人推出来的式子,跟我们推的不太一样,不过很相似了。
比赛AC,赛后RE,奇奇怪怪。
代码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
const ll mod = 1e9 + 9;
ll fac[maxn], a[maxn], b[maxn];
void init(){
a[0] = b[0] = fac[0] = 1;
for(int i = 1; i < maxn; i++){
fac[i] = fac[i - 1] * i % mod;
a[i] = a[i - 1] * 691504013 % mod;
b[i] = b[i - 1] * 308495997 % mod;
}
}
ll quick_pow(ll a, ll b){
ll ans = 1;
while(b){
if(b & 1){
ans = ans * a % mod;
}
a = a * a % mod;
b >>= 1;
}
return ans;
}
ll solve(ll n, ll C, ll k){
ll ans = 0; ll val = n % (mod - 1);
for(int r = 0; r <= k; r++){
ll t = a[k - r] * b[r] % mod;
t = quick_pow(t, C % (mod - 1));
ll x = fac[k];
ll y = fac[k-r] * fac[r] % mod;
ll c = x * quick_pow(y, mod - 2) % mod;//逆元
ll tmp = t * (quick_pow(t, val) - 1) % mod * quick_pow(t - 1, mod - 2) % mod;
if(t == 1)
tmp = n % mod;
tmp = tmp * c % mod;
if(r & 1)
ans -= tmp;
else
ans += tmp;
ans %= mod;
}
ll m = quick_pow(383008016, mod - 2);
ans = ans * quick_pow(m, k) % mod;
ans = (ans % mod + mod) % mod;
return ans;
}
ll n, c, k;
int main(){
init();
int t;
scanf("%d", &t);
while(t--){
scanf("%lld %lld %lld", &n, &c, &k);
printf("%lld\n", solve(n, c, k));
}
return 0;
}