[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}) $$

#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();
}
AA

 

posted @ 2017-10-15 21:23  A_LEAF  阅读(178)  评论(0编辑  收藏  举报