zoukankan      html  css  js  c++  java
  • HDU 6755 (数论综合题,2020多校)

    题目:传送门

    题意

    定义 Fn 为斐波那契第 n 项,递推式为

    输入 N,C,K(1 <= N,C <= 1e18, 1 <= K <= 1e5), 求

     输出答案对 1e9 + 9 取模

    思路

    参考博客

    首先,需要知道斐波那契数列的通项公式

     然后我们可以用二次剩余,求出 sqrt(5) 在 mod 1e9 + 9 意义下的值,然后再对其求一下逆元,就得到 1 / sqrt(5) 在 mod 1e9 + 9 的值,这样,(1 + sqrt(5)) / 2 和 (1 - sqrt(5)) / 2 在 mod 1e9 + 9 意义下的值都可以求得。

    后面的都是二项式的展开,和一些优化,这题卡常,没有优化的话会超时,具体的可以看参考博客。

    #include <bits/stdc++.h>
    #define LL long long
    #define ULL unsigned long long
    #define UI unsigned int
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF 0x3f3f3f3f
    #define inf LLONG_MAX
    #define PI acos(-1)
    #define fir first
    #define sec second
    #define lb(x) ((x) & (-(x)))
    #define dbg(x) cout<<#x<<" = "<<x<<endl;
    using namespace std;
    
    const int N = 1e6 + 5;
    
    const LL mod = 1e9 + 9;
    
    LL fac[N], ifac[N], n, c;
    
    int k;
    
    LL ksm(LL a, LL b) {
    
        a %= mod;
    
        if(b > mod) b = b % (mod - 1) + mod - 1;
    
        LL res = 1LL;
    
        while(b) {
    
            if(b & 1) res = res * a % mod;
    
            a = a * a % mod; b >>= 1;
    
        }
    
        return res;
    
    }
    
    LL C(int n, int m) {
    
        return fac[n] * ifac[m] % mod * ifac[n - m] % mod;
    
    }
    
    void solve() {
    
        scanf("%lld %lld %d", &n, &c, &k);
    
        LL inv_SqrtFive = 276601605; LL A = ksm(691504013, c); LL B = ksm(308495997, c);
    
        LL an = ksm(A, k); LL bn = 1LL; LL ifac_A = ksm(A, mod - 2);
    
        LL ans = 0LL;
    
        rep(i, 0, k) {
    
            LL res = an * bn % mod, tmp;
    
            if(res == 1LL) tmp = n % mod;
    
            else tmp = res * (ksm(res, n) - 1LL) % mod * ksm(res - 1, mod - 2) % mod;
    
            tmp = tmp * C(k, i) % mod;
    
            if(i & 1) ans = (ans - tmp + mod) % mod;
    
            else ans = (ans + tmp) % mod;
    
            an = an * ifac_A % mod;
    
            bn = bn * B % mod;
    
        }
    
        ans = ans * ksm(inv_SqrtFive, k) % mod;
    
        printf("%lld
    ", ans);
    
    }
    
    
    int main() {
    
        fac[0] = 1LL;
    
        for(int i = 1; i <= 100000; i++) fac[i] = 1LL * i * fac[i - 1]% mod;
    
        ifac[100000] = ksm(fac[100000], mod - 2);
    
        dep(i, 0, 99999) ifac[i] = 1LL * (i + 1LL) * ifac[i + 1] % mod;
    
        int _; scanf("%d", &_);
        while(_--) solve();
    
    //    solve();
    
        return 0;
    }
  • 相关阅读:
    Android_AsyncTask
    table隔行变色【转】
    添加对WCF的调用(内网状态下)。
    【转】IDEA 2017破解 license server激活
    C# LIst去重
    框架内事务的近期发现,以后再研究
    启动、停止、删除Windows服务
    软件项目总结中的经验总结
    iis最大连接数和队列长度
    在一个千万级的数据库查寻中,如何提高查询效率?
  • 原文地址:https://www.cnblogs.com/Willems/p/13371039.html
Copyright © 2011-2022 走看看