[bzoj4563] [Haoi2016]放棋子
交换一下行列对答案显然是没有影响的。。
所以先把障碍都挪到主对角线上。。然后就是错排问题了.....
f[i]=(f[i-1]+f[i-2])*(i-1)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #define ll long long 6 using namespace std; 7 const int modd=10000; 8 int d[2333],c[2333],b[2333],a[2333]; 9 int i,j,k,n,m; 10 11 int ra;char rx; 12 inline int read(){ 13 rx=getchar(),ra=0; 14 while(rx<'0'||rx>'9')rx=getchar(); 15 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra; 16 } 17 inline void addtoc(){ 18 int len=max(a[0],b[0]),i; 19 memset(c,0,(c[0]+1)<<2); 20 for(i=1;i<=len;i++){ 21 c[i]+=a[i]+b[i]; 22 if(c[i]>=modd)c[i]-=modd,c[i+1]++; 23 } 24 if(c[len+1])len++;c[0]=len; 25 } 26 inline void multoc(int x){ 27 int i,len=c[0]; 28 for(i=1;i<=len;i++){ 29 d[i]+=c[i]*x; 30 if(d[i]>=modd)d[i+1]+=d[i]/modd,d[i]%=modd; 31 } 32 if(d[len+1])len++; 33 memcpy(c,d,(len+1)<<2),c[0]=len, 34 memset(d,0,(len+1)<<2); 35 } 36 int main(){ 37 n=read(); 38 a[0]=b[0]=1,a[1]=1,b[1]=0; 39 for(i=2;i<=n;i++){ 40 addtoc(),multoc(i-1); 41 memcpy(a+1,b+1,max(a[0],b[0])<<2),a[0]=b[0], 42 memcpy(b+1,c+1,max(b[0],c[0])<<2),b[0]=c[0]; 43 } 44 printf("%d",b[b[0]]); 45 for(i=b[0]-1;i;i--)printf("%04d",b[i]);puts(""); 46 }