zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)

    题意:求Σfi^m%p。 zoj上p是1e9+7,牛客是1e9;  对于这两个,分别有不同的做法。

    前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可。     后者mod=1e9,5才mod下没有二次剩余,所以不能这么做了。可以分解mod,然后利用循环节搞。

     zoj:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 100005;
    const LL MOD = 1000000009;
    LL fac[N],A[N],B[N];
    void Init()
    {
        fac[0] = 1;
        for(int i=1; i<N; i++)
            fac[i] = fac[i-1] * i % MOD;
        A[0] = B[0] = 1;
        for(int i=1; i<N; i++)
        {
            A[i] = A[i-1] * 691504013 % MOD;
            B[i] = B[i-1] * 308495997 % MOD;
        }
    }
    LL quick_mod(LL a,LL b,LL MOD)
    {
        LL ans = 1;
        a %= MOD;
        while(b){
            if(b&1){
                ans = ans * a % MOD;
                b--;
            }
            b>>=1; a = a * a % MOD;
        }
        return ans;
    }
    
    LL Solve(LL n,LL k)
    {
        LL ans = 0;
        for(int r=0; r<=k; r++)
        {
            LL t = A[k-r] * B[r] % MOD;
            LL x = fac[k];
            LL y = fac[k-r] * fac[r] % MOD;
            LL c = x * quick_mod(y,MOD-2,MOD) % MOD;
            LL tmp = t * (quick_mod(t,n,MOD) - 1) % MOD * quick_mod(t-1,MOD-2,MOD) % MOD;
            if(t == 1) tmp = n % MOD;
            tmp = tmp * c % MOD;
            if(r & 1) ans -= tmp;
            else      ans += tmp;
            ans %= MOD;
        }
        LL m = quick_mod(383008016,MOD-2,MOD);
        ans = ans * quick_mod(m,k,MOD) % MOD;
        ans = (ans % MOD + MOD) % MOD;
        return ans;
    }
    
    int main()
    {
        int T;
        LL n,k;
        Init();
        scanf("%d",&T);
        while(T--)
        {
            cin>>n>>k;
            cout<<Solve(n,k)<<endl;
        }
        return 0;
    }
    View Code

    牛客:  你可以不熟悉斐波拉契的循环节具体怎么求,但是只要知道mod=p^a,fib[]%mod的循环节小于p^(a-1)* (2*p+2)。

    而1e9计较特殊,1e9=2^9*5^9,这两部分对应的循环节都不是很大,所以我们可以分别求,然后中国剩余定理合并啊,就可以水过去了。

    (但是我的代码怎么这么慢啊

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int Mod=1e9;
    int md[2]={512,1953125};
    int f[8000000],ans[2];
    int qpow(int a,int x,int p)
    {
        int res=1; while(x){
            if(x&1) res=1LL*res*a%p;
            x>>=1; a=1LL*a*a%p;
        } return res;
    }
    void exgcd(int a,int b,int &x,int &y)
    {
        if(b==0){ x=1; y=0; return;}
        exgcd(b,a%b,y,x); y-=a/b*x;
    }
    int rev(int a,int b)
    {
        int x,y; exgcd(a,b,x,y);
        x=(x%b+b)%b; return x;
    }
    int main()
    {
        int N,M;
        scanf("%d%d",&N,&M);
        rep(k,0,1) {
            f[0]=0; f[1]=1; int j=2;
            for(;;j++){
                f[j]=(f[j-1]+f[j-2]);
                if(f[j]>=md[k]) f[j]-=md[k];
                if(f[j]==1&&f[j-1]==0) {
                    j--; break;
                }
            }
            int P=N/j;
            for(int i=0;i<j;i++) {
                int t=qpow(f[i],M,md[k]);
                ans[k]=(ans[k]+1LL*t*(P+(i<=N%j)))%md[k];
            }
        }
        int res=(1LL*ans[0]*md[1]%Mod*rev(md[1],md[0])%Mod+1LL*ans[1]*md[0]%Mod*rev(md[0],md[1])%Mod)%Mod;
        printf("%d
    ",res);
        return 0;
    }
  • 相关阅读:
    jQuery jsonp(转载)
    vue jsonp (转载)
    Win10系统 开机总是黑屏一分钟 然后才进入解锁界面?
    Win10怎么取消开机密码
    Qt启动报错“0xc0000005”错误?
    公司转让债务问题怎么处理
    从车载激光点云数据轨迹数据中提取坐高斯标数据
    macbook air和pro的ppi
    任务管理器是灰色的
    python列表删除某个元素
  • 原文地址:https://www.cnblogs.com/hua-dong/p/11363229.html
Copyright © 2011-2022 走看看