勉強になりました。
https://yukicoder.me/problems/no/980
問題
整数pに対し、以下の数列を考える。
クエリとして正整数qが与えられる。以下の値をmod 10^9+7で答えよ。
解法
いくつかの解法がある。自分が最初思いついたのは数列を求めた後Garner法を使った任意modでのNTTだった。
Editorialの解法も興味深いが、自分はTLで(最近流行りの?)母関数解法を見かけたのでそちらで解いた。
まず、数列aが1-indexedだと面倒なので、0-indexedで考える。すなわちa_0=0, a_1=1だし、クエリはqから2を引いておいてを求めればよい。
まず元の数列aの母関数f(x)を求めよう。f(x)=yと置くと
なので式変形するととなる。
次にS_qを考えるわけだが、これは式の形を考えるとS_qの母艦数g(x)=f^2(x)であることがわかる。
するととなる。
よってもとに戻すととなるので、S_0~S_3を最初に求めておけばあとはS_qを順次前計算できる。
int N; ll P; ll mo=1000000007; ll A[2020202]; int Q; void solve() { int i,j,k,l,r,x,y; string s; cin>>P; A[2]=1; A[3]=2*P%mo; for(i=4;i<=2020101;i++) { A[i]=2*P*A[i-1]%mo+(2-P*P%mo)*A[i-2]%mo-2*P%mo*A[i-3]%mo-A[i-4]; A[i]=(A[i]%mo+mo)%mo; } cin>>Q; while(Q--) { cin>>x; cout<<A[x-2]<<endl; } }
まとめ
母関数を使うテク、まだ慣れてないので徐々に慣れないとな。