zoukankan      html  css  js  c++  java
  • 2020 Multi-University Training Contest 1 . Fibonacci Sum 水题改编

    题意很简单,就是让你求这个东西,这个时候你发现,原题????

    https://blog.csdn.net/acdreamers/article/details/23039571

    哦,只是原来写过的哪一题的C是1,这个是1e18. 想都不用想,直接二项式展开,求等比数列的前n项和。

    你会得到第i项(一共k项):

    这个时候理所当然的想先用二次剩余求出来那几个用到的东西,a,b,1/sqrt(5)。

    1你用快速幂求了一下,一交,tle了。

    2 然后发现每个都求快速幂太蠢了,所以又优化优化,优化到除了求分母的逆元需要用到快速幂其他的都可以由上一项推出来,然后再交,又wa了。

    3 哦,原来这是等比数列,分母是1-q,如果q是1那不就错了吗?所以特判一下如果q是1,加的就是n*a1,a1是几?你看这个Sn,忽略这个组合数,a1不就和q完全相等吗,是1! 就这样a了。

    #include <bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long
    #define met(a, b) memset(a, b, sizeof(a))
    #define rep(i, a, b) for(int i = a; i <= b; i++)
    #define bep(i, a, b) for(int i = a; i >= b; i--)
    #define pb push_back
    #define mp make_pair
    #define debug cout << "KKK" << endl
    #define ls num*2
    #define rs num*2+1
    #define re return
    using namespace std;
    const ll mod = 1e9 + 9;
    const double PI = acos(-1);
    const ll INF = 2e18+1;
    const int inf = 1e9+5;
    const double eps = 1e-7;
    const int maxn = 1e5 + 5;
    // 逆元
    // sqrt(5) = 383008016;
    // a = (1+sqrt(5))/2 = 691504013;
    // b = (1-sqrt(5))/2 = 308495997;
    // 1/sqrt(5) = 276601605;
    ll A = 691504013, B = 308495997;
    ll sqrt5 = 383008016, invsqrt5 = 276601605;
    ll qsm(ll a, ll n){
        ll res = a%mod, sum = 1;
        while(n){
            if(n&1) sum = (sum*res)%mod;
            res = (res*res)%mod;
            n >>= 1;
        }
        return sum;
    }
    
    ll fac[maxn], f[maxn], inv[maxn];
    ll C(ll m, ll n){
        if(m < n) return 0;
        if(n == 0 || m == n) return 1;
        return fac[m]*inv[n]%mod*inv[m-n]%mod;
    }
    void init(){
        fac[1] = 1; 
        f[1] = 1;   
        inv[1] = 1; 
        for(ll i = 2; i <= 100000; i++){
            fac[i] = fac[i-1]*i%mod;
            f[i] = (mod - mod/i)*f[mod%i]%mod;
            inv[i] = inv[i-1]*f[i]%mod;
        }
    }
    
    ll sac[maxn], sbc[maxn];
    int main(){
        // ios::sync_with_stdio(false);
        // cin.tie(0); cout.tie(0);
        init();
        int t; scanf("%d", &t);
        while(t--){
            ll n, c, k; 
            scanf("%lld%lld%lld", &n,&c,&k);
            // n = 1e18, c = 1e18, k = 1e5;
            ll res = qsm(invsqrt5, k);
            ll ans = 0, flag = -1;
            ll x, y;
            ll ac = qsm(A, c), bc = qsm(B, c);
            sac[0] = 1, sbc[0] = 1;
            sac[1] = ac, sbc[1] = bc;
            rep(i, 1, k){
                sac[i] = sac[i-1]*ac%mod;
                sbc[i] = sbc[i-1]*bc%mod;
            }
            ll acn = qsm(qsm(A, c), n);
            ll bcn = qsm(qsm(B, c), n);
            ll invacn = qsm(acn, mod-2);
            ll invbcn = qsm(bcn, mod-2);
            ll now_acn = qsm(acn, k), now_bcn = 1;
            for(ll i = 0; i <= k; i++){
                flag *= -1;
                ll q = sac[k-i] * sbc[i] % mod;
                if(q == 1){
                    q = (n%mod)*C(k, i) % mod;
                    ans = (ans + flag*q%mod + mod) % mod; 
                }
                else{
                    x = (C(k, i)*sac[k-i]%mod) * sbc[i] % mod;
                    x = (1-(now_acn * now_bcn % mod) + mod) % mod * x % mod;
                    y = (1 - (sac[k-i] * sbc[i])%mod ) % mod;
                    y = qsm(y, mod-2);
                    ans = (ans + flag*x*y%mod + mod)%mod;
                }
                now_acn = (now_acn * invacn) % mod;
                now_bcn = (now_bcn * bcn) % mod;
            }
            cout << ans*res%mod << endl;
        }
        return 0;
    }
  • 相关阅读:
    .NET 分布式自增Id组件(解决自动分配机器Id、时间回拨问题)
    简洁实用Socket框架DotNettySocket
    Colder框架硬核更新(Sharding+IOC)
    .NET Core开源快速开发框架Colder发布 (NET Core2.1+AdminLTE版)
    .NET开源快速开发框架Colder发布 (NET452+AdminLTE版)
    .NET 跨平台RPC框架DotNettyRPC
    Web后台快速开发框架(.NET Core)
    Web后台快速开发框架
    EasyWcf------无需配置,无需引用,动态绑定,轻松使用
    C# .NET 0配置使用Wcf(半成品)
  • 原文地址:https://www.cnblogs.com/philo-zhou/p/13357136.html
Copyright © 2011-2022 走看看