BZOJ3468 : 滑雪
根据公式$x^k=\sum_{i=1}^k Stirling2(k,i)i!C(x,i)$,
设$f[i][j][k]$表示从$(i,j)$出发的所有路径的$C(路径长度,k)$的和,
根据$C(n,m)=C(n-1,m-1)+C(n-1,m)$,则有:
$f[now][k]=\sum(f[nxt][k]+f[nxt][k-1]+C(1,k))$
然后根据公式求出每种幂的答案即可。
时间复杂度$O(nmk+k^2)$。
#include<cstdio> #include<algorithm> const int N=305,M=N*N,P=12345; int n,m,K,cnt,i,j,k,o,x,y,d,C[N],ans[N],fac[N],S[N][N]; int a[N][N],pos[N][N],f[2][M],dx[4]={-1,1,0,0},dy[4]={0,0,-1,1}; struct E{int x,y;E(){}E(int _x,int _y){x=_x,y=_y;}}b[M]; inline bool cmp(const E&x,const E&y){return a[x.x][x.y]<a[y.x][y.y];} int main(){ scanf("%d%d%d",&n,&m,&K); for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%d",&a[i][j]),b[++cnt]=E(i,j); std::sort(b+1,b+cnt+1,cmp); for(i=1;i<=cnt;i++)pos[b[i].x][b[i].y]=i; for(k=o=0;k<=K;k++,o^=1)for(i=1;i<=cnt;i++){ f[o][i]=0; for(d=0;d<4;d++){ x=b[i].x+dx[d],y=b[i].y+dy[d]; if(x<1||x>n||y<1||y>m||a[x][y]>=a[b[i].x][b[i].y])continue; j=pos[x][y]; (f[o][i]+=f[o][j]+f[o^1][j]+(k<=1))%=P; } (C[k]+=f[o][i])%=P; } for(fac[1]=1,i=2;i<=K;i++)fac[i]=fac[i-1]*i%P; for(i=1;i<=K;i++)for(S[i][i]=j=1;j<i;j++)S[i][j]=(j*S[i-1][j]+S[i-1][j-1])%P; for(ans[0]=C[0],i=1;i<=K;i++)for(j=1;j<=i;j++)(ans[i]+=S[i][j]*fac[j]%P*C[j])%=P; for(i=0;i<=K;i++)printf("%d\n",ans[i]); return 0; }