[2020杭电多校第一场]1005 Fibonacci Sum(二次剩余 + 等比数列求和)
与此题几乎一样。(https://blog.csdn.net/acdreamers/article/details/23039571)
不过注意,好像出题人赛后加强数据了,在枚举0-k的时候,里面最多只能有一个快速幂,其他的都尽量用变量迭代代替。要不然t飞。
#include<bits/stdc++.h> #define ll long long #define PB push_back #define endl '\n' #define INF 0x3f3f3f3f #define LINF 0x3f3f3f3f3f3f3f3f #define ull unsigned long long #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r #define lowbit(x) (x & (-x)) #define rep(i, a, b) for(int i = a ; i <= b ; ++ i) #define per(i, a, b) for(int i = b ; i >= a ; -- i) #define clr(a, b) memset(a, b, sizeof(a)) #define in insert #define random(x) (rand()%x) #define PII(x, y) make_pair(x, y) #define fi first #define se second #define pi acos(-1) using namespace std; const int maxn = 1e5 + 1000; const ll mod = 1e9 + 9; const ll gh5 = 383008016; const ll inv5 = 276601605; const ll ta = 691504013; const ll tb = 308495997; int T; ll n, c, k; ll fa[maxn], fb[maxn], fac[maxn], inv[maxn], inv_fac[maxn]; ll ksm(ll a, ll b){ ll ans = 1, base = a % mod; while(b){ if(b & 1) ans = ans * base % mod; base = base * base % mod; b >>= 1; } return ans; } ll C(ll n, ll m){ if(n < m) return 0; if(n == m || m == 0) return 1; return fac[n] * inv_fac[m] % mod * inv_fac[n-m] % mod; } void init(){ fac[1] = 1; inv[1] = 1; inv_fac[1] = 1; rep(i, 2, 100000){ fac[i] = fac[i-1] * i % mod; inv[i] = (mod - (mod/i)) * inv[mod % i] % mod; inv_fac[i] = inv_fac[i-1] * inv[i] % mod; } } signed main(){ cin >> T; init(); while(T --){ ll ans = 0, A, B; scanf("%lld %lld %lld", &n, &c, &k); fa[0] = fb[0] = 1; A = ksm(ta, c); B = ksm(tb, c); rep(i, 1, k) fa[i] = fa[i-1] * A % mod, fb[i] = fb[i-1] * B % mod; ll Fa = ksm(A, n); ll Fb = ksm(B, n); ll ia = ksm(Fa, mod-2); ll na = ksm(Fa, k), nb = 1; rep(r, 0, k){ ll t = fa[k-r] * fb[r] % mod; ll tmp = 1; if(t == 1) tmp = C(k, r) * (n % mod) % mod; else tmp = C(k, r) * t % mod * (na * nb % mod - 1) % mod * ksm(t-1, mod-2) % mod; if(r & 1) ans = (ans - tmp + mod) % mod; else ans = (ans + tmp) % mod; na = na * ia % mod; nb = nb * Fb % mod; } ans = ans * ksm(inv5, k) % mod; cout << ans << endl; } return 0; }