[Haoi2016]放棋子
我是打表发现的规律
f[i]=f[i-1]*(i&1)*(-1)^i
其实这是一个错排计数
$$ f_0=0,f_1=1 $$
$$ f_i=(i-1)*(f_{i-1}+f_{i-2}) $$
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int LEN=2006; struct bign { int s[LEN],len; bign(){mem(s,0);len=1;} bign operator * (int c) { bign x=*this; int jin=0; for(int i=1;i<=x.len;++i) { x.s[i]=x.s[i]*c+jin; jin=x.s[i]/10; x.s[i]%=10; } while(jin) { x.s[++x.len]=jin%10; jin/=10; } return x; } bign operator + (int c) { bign x=*this; x.s[1]+=c; for(int i=1;i<=x.len;++i) { x.s[i+1]+=x.s[i]/10; x.s[i]%=10; } x.len+=10; while(x.s[x.len]==0&&x.len>1) --x.len; return x; } bign operator - (int c) { bign x=*this; x.s[1]-=c; for(int i=1;i<=x.len;++i) if(x.s[i]<0) { --x.s[i+1]; x.s[i]+=10; } while(x.s[x.len]==0&&x.len>1) --x.len; return x; } void out() { for(int i=len;i>=1;--i) printf("%d",s[i]); puts(""); } }; int n; bign an; int main(){ scanf("%d",&n); for(int i=2;i<=n;++i) { if(i&1) an=an*i-1; else an=an*i+1; } an.out(); }