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 }
  • 相关阅读:
    POJ 2236 Wireless Network(并查集)
    POJ 2010 Moo University
    POJ 3614 Sunscreen(贪心,区间单点匹配)
    POJ 2184 Cow Exhibition(背包)
    POJ 1631 Bridging signals(LIS的等价表述)
    POJ 3181 Dollar Dayz(递推,两个long long)
    POJ 3046 Ant Counting(递推,和号优化)
    POJ 3280 Cheapest Palindrome(区间dp)
    POJ 3616 Milking Time(dp)
    POJ 2385 Apple Catching(01背包)
  • 原文地址:https://www.cnblogs.com/kirai/p/7424906.html
Copyright © 2011-2022 走看看