//generated by GPT-5.6 Terra, modified by hamamu template struct LagrangeInterpolation{ using ll = long long; // 補間に使う点の範囲と、その点での関数値を保存する。 ll sx,ex; vector ys; // cs[i] は i 番目のラグランジュ基底多項式に掛かる係数。 vector cs; // CMB は cmb.finv(i) で 1/i! を返せる型であればよい。 template LagrangeInterpolation(ll sx,ll ex,const vector &ys,CMB &cmb) :sx(sx),ex(ex),ys(ys) { // 補間点の範囲と、各点での値が矛盾しないことを確認する。 assert(sx<=ex); assert((ll)ys.size()==ex-sx+1); // i 番目の基底多項式の分母を逆元化して係数へ取り込む。 cs.resize(ex-sx+1); for(ll i=0;i<=ex-sx;++i){ cs[i]=ys[i]*cmb.finv(i)*cmb.finv(ex-sx-i); if((ex-sx-i)&1) cs[i]=-cs[i]; } } // 前後積を使い、各項から i 番目の因子だけを除いた積を O(1) で得る。 // 全体として O(ex-sx+1) で補間多項式の値を返す。 MINT get(ll x)const{ // 補間に使った点は、そのまま保存値を返せる。 if(sx<=x && x<=ex) return ys[x-sx]; const ll pointCount=ex-sx+1; vector lprod(pointCount+1,MINT(1)); vector rprod(pointCount+1,MINT(1)); // lprod[i] = (x-sx)(x-(sx+1))...(x-(sx+i-1))。 for(ll i=0;i0;--i){ rprod[i-1]=rprod[i]*MINT(x-(sx+i-1)); } // i 番目の因子を除いた積に、前計算済み係数を掛けて足し合わせる。 MINT result=0; for(ll i=0;i ys={5,9,15,23,33}; // ys[i]=f(sx+i) combination cmb(ex-sx); // cmb.finv(i) のみ使われる LagrangeInterpolation li(sx,ex,ys,cmb); mll result=li.get(10); // f(10) を O(N:補間点数) で計算 */