zoukankan      html  css  js  c++  java
  • [HDOJ6172] Array Challenge(线性递推,黑科技)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6172

    题意:给一堆东西,就是求个线性递推式,求第n项%1e9+7

    杜教板真牛逼啊,线性递推式用某特征值相关的论文板,打表前几项丢进去就出结果了。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long ll;
     5 #define rep(i,a,n) for (ll i=a;i<n;i++)
     6 #define per(i,a,n) for (ll i=n-1;i>=a;i--)
     7 #define pb push_back
     8 #define mp make_pair
     9 #define all(x) (x).begin(),(x).end()
    10 #define fi first
    11 #define se second
    12 #define SZ(x) ((ll)(x).size())
    13 typedef vector<ll> VI;
    14 typedef pair<ll,ll> PII;
    15 const ll mod=1000000007;
    16 ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
    17 // head
    18 
    19 ll _,n;
    20 namespace linear_seq {
    21     const ll N=10010;
    22     ll res[N],base[N],_c[N],_md[N];
    23 
    24     vector<ll> Md;
    25     void mul(ll *a,ll *b,ll k) {
    26         rep(i,0,k+k) _c[i]=0;
    27         rep(i,0,k) if (a[i]) rep(j,0,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
    28         for (ll i=k+k-1;i>=k;i--) if (_c[i])
    29             rep(j,0,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
    30         rep(i,0,k) a[i]=_c[i];
    31     }
    32     ll solve(ll n,VI a,VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
    33 //        printf("%d
    ",SZ(b));
    34         ll ans=0,pnt=0;
    35         ll k=SZ(a);
    36         assert(SZ(a)==SZ(b));
    37         rep(i,0,k) _md[k-1-i]=-a[i];_md[k]=1;
    38         Md.clear();
    39         rep(i,0,k) if (_md[i]!=0) Md.push_back(i);
    40         rep(i,0,k) res[i]=base[i]=0;
    41         res[0]=1;
    42         while ((1ll<<pnt)<=n) pnt++;
    43         for (ll p=pnt;p>=0;p--) {
    44             mul(res,res,k);
    45             if ((n>>p)&1) {
    46                 for (ll i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0;
    47                 rep(j,0,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
    48             }
    49         }
    50         rep(i,0,k) ans=(ans+res[i]*b[i])%mod;
    51         if (ans<0) ans+=mod;
    52         return ans;
    53     }
    54     VI BM(VI s) {
    55         VI C(1,1),B(1,1);
    56         ll L=0,m=1,b=1;
    57         rep(n,0,SZ(s)) {
    58             ll d=0;
    59             rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod;
    60             if (d==0) ++m;
    61             else if (2*L<=n) {
    62                 VI T=C;
    63                 ll c=mod-d*powmod(b,mod-2)%mod;
    64                 while (SZ(C)<SZ(B)+m) C.pb(0);
    65                 rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
    66                 L=n+1-L; B=T; b=d; m=1;
    67             } else {
    68                 ll c=mod-d*powmod(b,mod-2)%mod;
    69                 while (SZ(C)<SZ(B)+m) C.pb(0);
    70                 rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
    71                 ++m;
    72             }
    73         }
    74         return C;
    75     }
    76     ll gao(VI a,ll n) {
    77         VI c=BM(a);
    78         c.erase(c.begin());
    79         rep(i,0,SZ(c)) c[i]=(mod-c[i])%mod;
    80         return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
    81     }
    82 };
    83 
    84 signed main() {
    85     // freopen("in", "r", stdin);
    86     for (scanf("%lld",&_);_;_--) {
    87         scanf("%lld",&n);
    88         printf("%lld
    ",linear_seq::gao(VI{31,197,1255,7997,50959,324725,2069239,13185773,84023455},n-2));
    89     }
    90 }
  • 相关阅读:
    取代iframe,实现页面中引入别的页面
    axios请求
    接口跨域
    es7,es8
    promise
    移动端开发调试工具神器--Weinre使用方法
    资本论第一卷笔记
    2018春季实习生校招面经(一)阿里篇
    linux小实验-考勤模拟程序
    在基于debian的deepin或者Ubuntu上双等号“==”和双中括号“[[]]”不能使用的真相
  • 原文地址:https://www.cnblogs.com/kirai/p/7424906.html
Copyright © 2011-2022 走看看