杭电多校第一场 Fibonacci Sum
题解:
https://blog.csdn.net/acdreamers/article/details/23039571
按照这个博客可以推出式子,但是直接按照这个写会tle,所以要进行优化。
https://www.cnblogs.com/lonely-wind-/p/13364393.html
按照这个博客对快速幂进行优化即可。
看完之后建议自己从头到尾再手推一遍,加深印象。
先贴一下最开始的那份代码:
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const int mod = 1e9+9;
ll fac[maxn],A[maxn],B[maxn];
void Init() {
fac[0] = 1;
for (int i = 1; i < maxn; i++)
fac[i] = fac[i - 1] * i % mod;
A[0] = B[0] = 1;
for (int i = 1; i < maxn; i++) {
A[i] = A[i - 1] * 691504013 % mod;
B[i] = B[i - 1] * 308495997 % mod;
}
}
long long binpow(long long x,long long k) {
long long ans = 1;
while (k) {
if (k & 1) ans = ans * x % mod;
x = x * x % mod;
k >>= 1;
}
return ans;
}
int main() {
int t;
Init();
scanf("%d", &t);
ll f = 383008016;
ll m = binpow(f, mod - 2);
while (t--) {
ll n, c, k, ans = 0;
scanf("%lld%lld%lld", &n, &c, &k);
ll ac = binpow(A[1], c), bc = binpow(B[1], c);
for (int i = 0; i <= k; i++) {
ll q = binpow(ac, k - i) * binpow(bc, i) % mod, tmp = (n + 1) % mod,C = fac[k] % mod * binpow(fac[i] * fac[k - i] % mod, mod - 2);
if (q != 1) tmp = (binpow(q, n + 1) - 1 + mod) % mod * binpow(q - 1, mod - 2) % mod;
ll res = tmp * C % mod;
if (i & 1) ans = (ans - res + mod) % mod;
else ans = (ans + res) % mod;
}
ans = ans * binpow(m, k) % mod;
ans = (ans % mod + mod) % mod;
printf("%lld
", ans);
}
}
AC代码
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const int mod = 1e9+9;
inline ll read(){
ll X=0; bool flag=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
while(ch>='0'&&ch<='9') {X=(X<<1ll)+(X<<3ll)+ch-'0'; ch=getchar();}
if(flag) return X;
return ~(X-1);
}
long long binpow(long long x,long long k) {
long long ans = 1;
while (k) {
if (k & 1) ans = ans * x % mod;
x = x * x % mod;
k >>= 1;
}
return ans;
}
ll fac[maxn],A[maxn],B[maxn],fac_inv[maxn];
void Init() {
fac[0] = 1;
for (int i = 1; i < maxn; i++)
fac[i] = 1ll * fac[i - 1] * i % mod;
A[0] = B[0] = 1;
for (int i = 1; i < maxn; i++) {
A[i] = 1ll * A[i - 1] * 691504013 % mod;
B[i] = 1ll * B[i - 1] * 308495997 % mod;
}
fac_inv[1]=1,fac_inv[0]=1;
for (int i=2; i<maxn; i++) fac_inv[i]=binpow(fac[i],mod-2);
}
int main() {
Init();
int t = read();
ll m = binpow(383008016, mod - 2);
while (t--) {
ll n = read(), c = read(), k = read(), ans = 0;
ll q = binpow(A[k], c) % mod;
ll num = binpow(1ll * B[1] * binpow(A[1], mod - 2) % mod, c);
ll qn = binpow(q, n) % mod;
ll val = binpow(num, n) % mod;
for (int i = 0; i <= k; i++) {
ll C = 1ll * fac[k] * fac_inv[k - i] % mod * fac_inv[i] % mod;
ll tmp = 1ll * q * (qn - 1 + mod) % mod * binpow(q - 1, mod - 2) % mod;
if (q == 1) tmp = 1ll * n % mod;
tmp = tmp * C % mod;
if (i & 1) ans -= tmp;
else ans += tmp;
ans = (ans % mod + mod) % mod;
q = 1ll * q * num % mod;
qn = 1ll * qn * val % mod;
}
ans = ans * binpow(m, k) % mod;//!!!
printf("%lld
", ans);
}
return 0;
}