BZOJ4451 : [Cerc2015]Frightful Formula
$(i,1)$对答案的贡献为$l_iC(2n-i-2,n-i)a^{n-1}b^{n-i}$。
$(1,i)$对答案的贡献为$t_iC(2n-i-2,n-i)*a^{n-i}b^{n-1}$。
$(i,j)$的$c$对答案的贡献为$cC(2n-i-j,n-i)a^{n-j}b^{n-i}$。
$c$总的贡献为:
\[\begin{eqnarray*}
&&c\sum_{i=2}^n\sum_{j=2}^nC(2n-i-j,n-i)a^{n-j}b^{n-i}\\
&=&c\sum_{i=2}^n\sum_{j=2}^n(2n-i-j)!\times\frac{a^{n-j}}{(n-j)!}\times\frac{b^{n-i}}{(n-i)!}\\
&=&c\sum_{i=2}^n\sum_{j=2}^n(2n-i-j)!A_jB_i
\end{eqnarray*}\]
设
\[\begin{eqnarray*}
A_i=\frac{a^{n-i}}{(n-i)!}\\
B_i=\frac{b^{n-i}}{(n-i)!}
\end{eqnarray*}\]
则
\[\begin{eqnarray*}
ans+=c\sum_{i=4}^{2n}(2n-i)!\sum_{j=0}^i A_{i-j}B{j}
\end{eqnarray*}\]
FFT mod any prime即可。
时间复杂度$O(n\log n)$。
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int N=524300,P=1000003,M=1000; int n,a,b,c,i,j,k,pos[N],ans; int pa[N],pb[N],fac[N],inv[N],A[N],B[N],C[N]; inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';} namespace FFT{ struct comp{ long double r,i;comp(long double _r=0,long double _i=0){r=_r;i=_i;} comp operator+(const comp x){return comp(r+x.r,i+x.i);} comp operator-(const comp x){return comp(r-x.r,i-x.i);} comp operator*(const comp x){return comp(r*x.r-i*x.i,r*x.i+i*x.r);} comp conj(){return comp(r,-i);} }A[N],B[N]; int a0[N],b0[N],a1[N],b1[N]; const long double pi=acos(-1.0); void FFT(comp a[],int n,int t){ for(int i=1;i<n;i++)if(i<pos[i])swap(a[i],a[pos[i]]); for(int d=0;(1<<d)<n;d++){ int m=1<<d,m2=m<<1; long double o=pi*2/m2*t;comp _w(cos(o),sin(o)); for(int i=0;i<n;i+=m2){ comp w(1,0); for(int j=0;j<m;j++){ comp&A=a[i+j+m],&B=a[i+j],t=w*A; A=B-t;B=B+t;w=w*_w; } } } if(t==-1)for(int i=0;i<n;i++)a[i].r/=n; } void mul(int*a,int*b,int*c){//c=a*b int i,j; for(i=0;i<k;i++)A[i]=comp(a[i],b[i]); FFT(A,k,1); for(i=0;i<k;i++){ j=(k-i)&(k-1); B[i]=(A[i]*A[i]-(A[j]*A[j]).conj())*comp(0,-0.25); } FFT(B,k,-1); for(i=0;i<k;i++)c[i]=((long long)(B[i].r+0.5))%P; } //输入两个多项式,求a*b mod P,保存在c中,c不能为a或b void mulmod(int*a,int*b,int*c){ int i; for(i=0;i<k;i++)a0[i]=a[i]/M,b0[i]=b[i]/M; for(mul(a0,b0,a0),i=0;i<k;i++){ c[i]=1LL*a0[i]*M*M%P; a1[i]=a[i]%M,b1[i]=b[i]%M; } for(mul(a1,b1,a1),i=0;i<k;i++){ c[i]=(a1[i]+c[i])%P,a0[i]=(a0[i]+a1[i])%P; a1[i]=a[i]/M+a[i]%M,b1[i]=b[i]/M+b[i]%M; } for(mul(a1,b1,a1),i=0;i<k;i++)c[i]=(1LL*M*(a1[i]-a0[i]+P)+c[i])%P; } } int main(){ read(n),read(a),read(b),read(c); for(pa[0]=i=1;i<=n;i++)pa[i]=1LL*pa[i-1]*a%P; for(pb[0]=i=1;i<=n;i++)pb[i]=1LL*pb[i-1]*b%P; for(fac[0]=i=1;i<=n+n;i++)fac[i]=1LL*fac[i-1]*i%P; for(inv[0]=inv[1]=1,i=2;i<=n;i++)inv[i]=1LL*(P-inv[P%i])*(P/i)%P; for(i=1;i<=n;i++)inv[i]=1LL*inv[i]*inv[i-1]%P; for(i=1;i<=n;i++){ read(j); if(i>1)ans=(1LL*fac[n+n-i-2]*inv[n-i]%P*pa[n-1]%P*pb[n-i]%P*j+ans)%P; } for(i=1;i<=n;i++){ read(j); if(i>1)ans=(1LL*fac[n+n-i-2]*inv[n-i]%P*pa[n-i]%P*pb[n-1]%P*j+ans)%P; } ans=1LL*ans*inv[n-2]%P; for(k=1;k<=n;k<<=1);k<<=1; j=__builtin_ctz(k)-1; for(i=0;i<k;i++)pos[i]=pos[i>>1]>>1|((i&1)<<j); for(i=2;i<=n;i++)A[i]=1LL*pa[n-i]*inv[n-i]%P; for(i=2;i<=n;i++)B[i]=1LL*pb[n-i]*inv[n-i]%P; FFT::mulmod(A,B,C); for(i=4;i<=n+n;i++)ans=(1LL*C[i]*fac[n+n-i]%P*c+ans)%P; return printf("%d",ans),0; }