N!(hdu1042)

Posted sydevil

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了N!(hdu1042)相关的知识,希望对你有一定的参考价值。

N!

Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N!

Input

One N in one line, process to the end of file.

Output

For each N, output N! in one line.

Sample Input

1

2

3

Sample Output

1

2

6

思路:

压位高精(or FFT),当然压位只能卡过去,(FFT)时需要对数列分治,即为(prod_{i=l}^r=(prod_{i=l}^{mid}i)(prod_{i=mid+1}^{r}i))

原因:

我们可以发现,在(FFT)时我们需要把(2)个序列强行拉高到(2^n)位,所以当参与乘法的(2)个序列(位数)越相近时(FFT)效率越高,所以我们把(frac{r!}{(l-1)!})拆为(frac{mid!}{(l-1)!}*frac{r!}{mid!},)一般(mid)(frac{l+r*2}{3})或黄金比例时最优。当然,(FFT)与压位共用更优,笔者取得(hdu)最优解

(mathfrak{Talk is cheap,show you the code.})

#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
# define read read1<int>()
# define Type template<typename T>
Type inline T read1(){
    T n=0;
    char k;
    bool fl=0;
    do (k=getchar())=='-'&&(fl=1);while('9'<k||k<'0');
    while(47<k&&k<58)n=(n<<3)+(n<<1)+(k^48),k=getchar();
    return fl?-n:n;
}
# define f(i,l,r) for(int i=(l);i<=(r);++i)
# define fre(k) freopen(k".in","r",stdin);freopen(k".ans","w",stdout)
const double PI=acos(-1);
class complex{
    public:
        double x,y;
        complex(){x=y=0;}
        complex(double _x,double _y):x(_x),y(_y){}
        complex operator * (complex b){return complex(x*b.x-y*b.y,x*b.y+y*b.x);} 
        complex operator + (complex b){return complex(x+b.x,y+b.y);}
        complex operator - (complex b){return complex(x-b.x,y-b.y);}
        complex operator * (double u){return complex(x*u,y*u);} 
        complex& operator *= (complex b){return *this=*this*b;} 
        complex& operator += (complex b){return *this=*this+b;} 
        complex& operator -= (complex b){return *this=*this-b;} 
};
# define int long long
class Array{
    private:
        vector<int>a;
    public:
        Array(){}
        void push(int n){a.push_back(n);}
        Array(int* l,int* r){while(l!=r)push(*l),++l;}
        int size(){return a.size();}
        int& operator [] (const int x){return a[x];}
};
void FFT(const int len,vector<complex>&a,const int Ty,int *r=NULL){
    if(!r){
        r=new int[len];
        r[0]=0;int L=log2(len);
        f(i,0,len-1){
            r[i]=(r[i>>1]>>1)|((i&1)<<L-1);
            if(i<r[i])swap(a[i],a[r[i]]);
        }
    }
    for(int i=1;i<len;i<<=1){
        complex T(cos(PI/i),Ty*sin(PI/i));
        for(int W=i<<1,j=0;j<len;j+=W){
            complex n(1,0);
            for(int k=0;k<i;++k,n*=T){
                complex x(a[j+k]),y(n*a[i+j+k]);
                a[j+k]=x+y;
                a[i+j+k]=x-y;
            }
        }
    }
}
Array operator * (Array x,Array y){
    int n=x.size()-1,m=y.size()-1;
    int limit=1;
    while(limit<=n+m)limit<<=1;
    vector<complex>_x(limit+1),_y(limit+1);
    Array ans;
    f(i,0,n)_x[i]=complex(x[i],0);
    f(i,0,m)_y[i]=complex(y[i],0);
    FFT(limit,_x,1);
    FFT(limit,_y,1);
    f(i,0,limit)_x[i]*=_y[i];
    FFT(limit,_x,-1);
    f(i,0,n+m)ans.push((int)(_x[i].x/limit+0.5));
    return ans;
}
void into(int n,Array &x){
    f(i,0,n)x.push(read);
}
Array change(int n){
    Array tem;
    do tem.push(n%100000);while(n/=100000);
    return tem;
}
Array carry(Array x){
    int tem=0;
    for(int i=0;i<x.size();++i){
        tem+=x[i];
        x[i]=tem%100000;
        tem/=100000;
    }
    while(tem)x.push(tem%100000),tem/=100000;
    return x;
}
# undef int
Array tem;
Array answer(int l,int r){
    if(l==r)return change(l);
    int mid=(l+2*r)/3;
    return carry(answer(l,mid)*answer(mid+1,r));
}
int main(){
    int op;
    while(~scanf("%d",&op)){
        if(op==0){puts("1");continue;}
        tem=answer(1,op);
        for(int i=tem.size();~--i;)
            if(i+1==tem.size())printf("%lld",tem[i]);
            else printf("%05lld",tem[i]);
        putchar('
');
    }
    return 0;
}

以上是关于N!(hdu1042)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1042N!

HDU 1042 N!

HDU - 1042 - N! - JAVA

N!(hdu1042)

HDU 1042 N!

N! hdu 1042