N的阶乘【大数阶乘】

输入N求N的阶乘的准确值。

Input

输入N(1 <= N <= 10000)

Output

输出N的阶乘


  首先,要确定N的阶乘的数位大概有多少位,这样便于我们去选择合适的算法。

  阶乘:1*2*3*\cdots *N要知道它是10的多少次,不妨

log_{10}{N!} = log_{10}{1} + log_{10}{2} + \cdots + log_{10}{N}

当N==10000时,上式值为35660(已经向上取整)。

  所以接受O(N^2)的算法,当大数的一位存的是9位数的时候。复杂度就合法了。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
//#include 
//#include 
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define eps 1e-8
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(x, y) make_pair(x, y)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const ull mod = 1e9;
int N, op;
vector a;
int len = 1;
void solve()
{
    a.push_back(1);
    ull tmp;
    for(ull i=2; i<=N; i++)
    {
        for(int j=len - 1; j>=0; j--)
        {
            a[j] = a[j] * i;
            if(a[j] >= mod)
            {
                if(j == len - 1)
                {
                    len++;
                    a.push_back(0);
                    tmp = a[j] / mod;
                    a[j + 1] += tmp;
                    a[j] -= tmp * mod;
                }
                tmp = a[j] / mod;
                a[j + 1] += tmp;
                a[j] -= tmp * mod;
            }
        }
    }
}
int main()
{
    scanf("%d", &N);
    if(N == 1) printf("1\n");
    else
    {
        solve();
        printf("%lld", a[len - 1]);
        for(int i = len - 2; i>=0; i--) printf("%.9lld", a[i]); printf("\n");
    }
    return 0;
}

 

你可能感兴趣的:(模拟)