【HDU6172】—Array Challenge(BM+常系数齐次线性递推)
大胆猜测这个东西有递推式
实际上也是有的
打出来是
然后该咋搞咋搞
#include<bits/stdc++.h>
using namespace std;
#define gc getchar
inline int read(){
char ch=gc();
int res=0,f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
#define re register
#define pb push_back
#define cs const
#define pii pair<int,int>
#define fi first
#define se second
#define ll long long
#define poly vector<int>
#define bg begin
cs int mod=1e9+7,G=3;
inline int add(int a,int b){return (a+=b)>=mod?a-mod:a;}
inline void Add(int &a,int b){(a+=b)>=mod?(a-=mod):0;}
inline int dec(int a,int b){return (a-=b)<0?a+mod:a;}
inline void Dec(int &a,int b){(a-=b)<0?(a+=mod):0;}
inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;}
inline void Mul(int &a,int b){a=mul(a,b);}
inline int ksm(int a,int b,int res=1){
for(;b;b>>=1,a=mul(a,a))(b&1)&&(res=mul(res,a));return res;
}
inline void chemx(ll &a,ll b){a<b?a=b:0;}
inline void chemn(ll &a,ll b){a>b?a=b:0;}
cs int N=(1<<19)|5;
inline poly operator +(poly a,poly b){
int deg=max(a.size(),b.size());
a.resize(deg),b.resize(deg);
for(int i=0;i<deg;i++)Add(a[i],b[i]);
return a;
}
inline poly operator -(poly a,poly b){
int deg=max(a.size(),b.size());
a.resize(deg),b.resize(deg);
for(int i=0;i<deg;i++)Dec(a[i],b[i]);
return a;
}
inline poly operator *(cs poly &a,cs poly &b){
int deg=(int)a.size()+(int)b.size()-1;
poly c(deg,0);
for(int i=0;i<a.size();i++)
for(int j=0;j<b.size();j++)
Add(c[i+j],mul(a[i],b[j]));
return c;
}
inline poly operator %(poly a,poly b){
int n=(int)a.size()-1,m=(int)b.size()-1;
if(n<m)return a;
for(int i=n;i>=m;i--){
int x=a[i];
for(int j=i,k=m;~k;k--,j--)Dec(a[j],mul(b[k],x));
}
a.resize(m);return a;
}
inline poly ksm(poly a,ll b,poly res,poly Mod){
for(;b;b>>=1,a=a*a%Mod)if(b&1)res=res*a%Mod;
return res;
}
namespace Cas{
poly f;int n;
inline void init(poly coef){
n=coef.size()-1;
f.resize(n+1);
for(int i=1;i<=n;i++)f[n-i]=dec(0,coef[i]),cout<<coef[i]<<" ";
f[n]=1;
}
inline int calc(int *v,ll k){
if(k<n)return v[k+1];
poly g(2),res(1,1);g[1]=1;
res=ksm(g,k,res,f);
int anc=0;
for(int i=0;i<n;i++)Add(anc,mul(v[i+1],res[i]));
return anc;
}
}
namespace B_M{
poly r[N];
int fail[N],del[N],a[N],n,cnt;
inline void update(int i){
++cnt;
int MUL=mul(dec(a[i],del[i]),ksm(dec(a[fail[cnt-2]],del[fail[cnt-2]]),mod-2));
r[cnt].resize(i-fail[cnt-2],0);
r[cnt].pb(MUL);
for(int j=1;j<r[cnt-2].size();j++){
r[cnt].pb(mul(mod-r[cnt-2][j],MUL));
}
r[cnt]=r[cnt]+r[cnt-1];
}
inline void BM(){
for(int i=1;i<=9;i++){
for(int j=1;j<r[cnt].size();j++){
Add(del[i],mul(a[i-j],r[cnt][j]));
}
if(a[i]!=del[i]){
fail[cnt]=i;
if(!cnt)r[++cnt].resize(i+1);
else update(i);
}
}
Cas::init(r[cnt]);
}
ll h[N],b[N];
inline void init(){
h[0]=2,h[1]=3,h[2]=6;n=9;
for(int i=3;i<=12;++i)h[i]=h[i-1]*4+h[i-2]*17-h[i-3]*12-16;
for(int i=1;i<=11;++i)b[i]=h[i+1]*h[i]*3+h[i+1]*h[i-1]*9+h[i]*h[i]*9+h[i]*h[i-1]*27-h[i+1]*18-h[i]*126-h[i-1]*81+192;
for(int i=1;i<=n;i++)a[i]=((ll)sqrt(b[i]+(1ll<<(i*2))))%mod;
BM();
}
}
int main(){
B_M::init();
int T=read();
while(T--){
ll k;
scanf("%lld",&k);
cout<<Cas::calc(B_M::a,k-1)<<'\n';
}
}