求k时刻一个标号转移到各位置的概率,最后枚举每个标号加权求期望。可以发现转移矩阵是循环矩阵,因此乘法是O(n^2)的。
另外用long double会WA,说明标程精度挂了,所以必须挂得和标程一样才能过。
另外这个乘法是圆周卷积的形式,如果取模的话就可以FFT了。
#include<cstdio> #define N 1000 typedef double flo; int n,m,k,i,j; double v; typedef flo arr[N]; arr s,t,u,q; void mul(flo*s,flo*t){ for(i=0;i!=n;++i) u[i]=0; for(i=0;i!=n;++i) for(j=0;j!=n;++j) u[(i+j)%n]+=s[i]*t[j]; for(i=0;i!=n;++i) s[i]=u[i]; } int main(){ scanf("%d%d%d",&n,&m,&k); for(i=0;i!=n;++i){ scanf("%lf",&v); t[i]=v; } q[0]=1-1./m; q[1]=1./m; for(s[0]=1;k;k/=2){ if(k%2) mul(s,q); if(k/2) mul(q,q); else mul(t,s); } for(i=0;i!=n;++i) printf("%.3f ",(double)t[i]); }