【CQOI2015】多项式题解 (NKOJ3252)
再次感谢Wikipedia提供公式支撑。
题面:Here
这道题其实很水,坑点在高精度。
给定 $F(x)=\sum^n_{k=0}a_kx^k=\sum^n_{k=0}b_k(x-t)^k$, 求给定$b_m$。
想都不想就是$F(x)$在$x=t$处的Taylor展开。
\begin{align}F(x)=\sum^n_{k=0}\frac{F^{(k)}(t)}{k!}(x-t)^k\end{align}
易知$b_m=\frac{F^{(m)}\ (t)}{m!}$, 而容易得到$\frac{F^{(m)}\ (t)}{m!}=\sum^{n-m}_{k=0}(^{m+k}_{\ \ \ \ k})a_{m+k}t^k$,
至于{$a_k$},因为$mod\ 3389$意义下的数是有限的,显然有循环节,跑一遍就知道$a_k=a_{k\ mod\ 3388}$, 剩下的就只剩下写个高精度乱搞了。
(然而自己过于菜,写个高精度调一下午。。。
(分段一定1e9!!!
Code:
#include<bits/stdc++.h> using namespace std; typedef long long ll; int a; const int MOD=1e9; struct Big { ll S[10000],T,cur; void Input() { string s;cin>>s;int i,t,l=s.size(); for(i=0;i<l;i++) t=(l-i-1)/9,S[t]=S[t]*10+s[i]-48,T=T*10+s[i]-48,T%=3388; cur=(l-1)/9;while(cur>0&&S[cur]==0) cur--; } void Divide(int k) { for(int i=cur;i>0;i--) { S[i-1]+=S[i]%k*MOD;S[i]/=k; if(S[cur]==0) cur--; } S[0]/=k; } void Add(int k) { S[0]+=k;int i=0; while(S[i]>=MOD) S[i+1]+=S[i]/MOD,S[i++]%=MOD; if(S[cur+1]) cur++; } void Add(const Big& o) { int i,r=max(o.cur,cur); for(i=0;i<=r;i++) { S[i]+=o.S[i]; if(S[i]>=MOD) S[i+1]+=S[i]/MOD,S[i]%=MOD; } cur=r+5;while(cur>0&&S[cur]==0) cur--; } void Multiply(const Big& o,Big& E) { int i,j;memset(&E,0,sizeof(E)); for(i=0;i<=cur;i++) for(j=0;j<=o.cur;j++) { E.S[i+j]+=S[i]*o.S[j]; if(E.S[i+j]>=MOD) { E.S[i+j+1]+=E.S[i+j]/MOD; E.S[i+j]%=MOD; } } E.cur=cur+o.cur+5; while(E.S[E.cur]==0) E.cur--; } void Print() { printf("%lld",S[cur]); ll i,k; for(i=cur-1;i>=0;i--) { k=MOD/10; while(k>S[i]) putchar('0'),k/=10; if(k) printf("%lld",S[i]); } } } N,M,J[10],T[2],R[2],Q,P[2],ANS; int K,k,i,j; int main() { N.Input();J[1].Input();M.Input();K=N.T-M.T;K+=K<0?3388:0; a=1;for(i=1;i<=M.T;i++) a=(1234*a+5678)%3389; // cout<<N.T<<' '<<M.T<<endl; ANS.Add(a);T[0].S[0]=1; // N.Print();puts(""); // J[1].Print();puts(""); // M.Print();puts(""); for(k=1;k<=K;k++) { M.Add(1); // M.Print();puts(""); T[k-1&1].Multiply(M,T[k&1]); // T[k].Print(); a=(1234*a+5678)%3389; Q.S[0]=a; T[k&1].Divide(k);//T[k].Print(); T[k&1].Multiply(Q,R[k&1]); if(k<K) J[k].Multiply(J[1],J[k+1]); J[k].Multiply(R[k&1],P[k&1]); ANS.Add(P[k&1]); } ANS.Print(); // N.Input();M.Input(); // N.Multiply(M,ANS); // ANS.Print(); }
代码风格过于丑,请自动忽略各种调试语句。