• 线性递推模板


    #include<bits/stdc++.h>
     
    using namespace std;
     
    #define rep(i,a,n) for(int i=a;i<n;i++)
     
    #define SZ(x) ((int)(x).size())
    typedef vector<int> VI;
    typedef long long ll;
     
    const ll mod = 1e9+7;
     
    ll powmod(ll a,ll b) {
        ll ret = 1;
        a%=mod;
        while(b) {
            if(b&1) ret = ret*a%mod;
            a = a*a%mod;
            b>>=1;
        }
        return ret;
    }
    int _,n;
     
    namespace linear_seq {
    const int N = 10010;
    ll res[N],base[N],_c[N],_md[N];
    vector<int> Md;
     
    void mul(ll *a,ll *b,int k) {
        for(int i=0; i<k+k; i++)
            _c[i] = 0;
        for(int i=0; i<k; ++i)
            if(a[i])
                for(int j=0; j<k; j++)
                    _c[i+j] = (_c[i+j]+a[i]*b[j])%mod;
     
        for(int i=k+k-1; i>=k; i--)
            if(_c[i])
                for(int j=0; j<(int) Md.size(); j++)
                    _c[i-k+Md[j]] = (_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
        for(int i=0; i<k; i++)
            a[i] = _c[i];
    }
     
    int solve(ll n,VI a,VI b) {
        ll ans = 0,pnt = 0;
        int k = SZ(a);
        for(int i=0; i<k; i++)
            _md[k-1-i] = -a[i];
        _md[k] = 1;
        Md.clear();
        for(int i=0; i<k; i++)
            if(_md[i]!=0)
                Md.push_back(i);
        for(int i=0; i<k; i++)
            res[i] = base[i] = 0;
        res[0] = 1;
        while((1ll<<pnt)<=n)
            pnt++;
     
        for(int p = pnt; p>=0; p--) {
            mul(res,res,k);
            if((n>>p)&1) {
                for(int i=k-1; i>=0; i--) res[i+1] = res[i];
                res[0]  = 0;
                for(int j=0; j<(int) Md.size(); ++j)
                    res[Md[j]] = (res[Md[j]]-res[k]*_md[Md[j]])%mod;
            }
        }
        rep(i,0,k) ans = (ans+res[i]*b[i])%mod;
        if(ans<0) ans+=mod;
        return ans;
    }
     
    VI BM(VI s) {
        VI C(1,1),B(1,1);
        int L = 0,m = 1,b = 1;
        for(int n=0; n<(int)s.size(); ++n) {
            ll d = 0;
            for(int i=0; i<L+1; i++)
                d = (d+(ll)C[i]*s[n-i])%mod;
            if(d==0) ++m;
            else if(2*L<=n) {
                VI T=C;
                ll c = mod-d*powmod(b,mod-2)%mod;
                while(SZ(C)<SZ(B)+m)
                    C.push_back(0);
                for(int i=0; i<(int) B.size(); i++)
                    C[i+m] = (C[i+m]+c*B[i])%mod;
                L = n+1-L;
                B = T;
                b = d;
                m = 1;
            } else {
                ll c = mod-d*powmod(b,mod-2)%mod;
                while(SZ(C)<SZ(B)+m)
                    C.push_back(0);
                for(int i=0; i<(int)B.size(); i++)
                    C[i+m] = (C[i+m]+c*B[i])%mod;
                ++m;
            }
        }
        return C;
    }
     
    ll gao(VI a,ll n) {
        VI c = BM(a);
        c.erase(c.begin());
        for(int i=0; i<(int) c.size(); i++)
            c[i] = (mod-c[i])%mod;
        return (ll) solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
    }
     
    }
     
    int main() {
        ll t;
        ll nnn;
        VI a;
        a.push_back(3);
        a.push_back(9);
        a.push_back(20);
        a.push_back(46);
        a.push_back(106);
        a.push_back(244);
        a.push_back(560);
        a.push_back(1286);
        a.push_back(2956);
        a.push_back(6794);
        scanf("%lld",&t);
        while(t--) {
            scanf("%lld",&nnn);
            printf("%lld
    ",linear_seq::gao(a,nnn-1));
        }
    }
    View Code
  • 相关阅读:
    大厂面试高频Redis,记不住的多操作几次吧
    自动化测试系列之jenkins配置搭建环境
    关于linux服务器的磁盘监控的相关知识
    前端常见一些安全问题及解决方案
    如何使用PM2部署前端项目
    vuex状态管理器本地持久化
    关于在Vue中Typescript的写法
    websocket快速重连机制
    如何使用selenium打开多个浏览器
    运维人员踩坑记录之netplan遇坑,配置临时IP巧妙解决
  • 原文地址:https://www.cnblogs.com/xiaolaji/p/11290711.html
Copyright © 2020-2023  润新知