BM遞推
阿新 • • 發佈:2018-10-03
back ++ memset clu push type printf eof long
從別的大佬處看到的模板
#include<bits/stdc++.h> #define fi first #define se second #define INF 0x3f3f3f3f #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define pqueue priority_queue #define NEW(a,b) memset(a,b,sizeof(a)) #define Pii pair<int,int> #define VI vector<int> const doublepi=4.0*atan(1.0); const double e=exp(1.0); const int maxn=3e6+8; typedef long long LL; typedef unsigned long long ULL; const LL mod=1e9+7; const ULL base=1e7+7; using namespace std; LL qpow(LL a,LL b){ LL ans=1; a%=mod; while(b){ if(b&1){ans=ans*a%mod;} a=a*a%mod; b>>=1; } return ans; } LL n; namespace linear_seq{ const int N=10010; LL res[N],base[N],_c[N],_md[N]; VI 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=(int)(a).size(); assert((int)(a).size()==(int)(b).size()); 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; } } for(int i=0;i<k;i++) 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*qpow(b,mod-2)%mod; while ((int)(C).size()<(int)(B).size()+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*qpow(b,mod-2)%mod; while ((int)(C).size()<(int)(B).size()+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; } int 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 solve(n,c,VI(a.begin(),a.begin()+(int)(c).size())); } }; int main(){ int t; for(scanf("%d",&t);t;t--){ scanf("%lld",&n); printf("%d\n",linear_seq::gao(VI{1,3,5,7},n-1)); } }
BM遞推