码迷,mamicode.com
首页 > 其他好文 > 详细

N!(hdu1042)

时间:2019-12-16 22:12:08      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:change   getch   for   mes   algo   while   task   void   temp   

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('\n');
    }
    return 0;
}

N!(hdu1042)

标签:change   getch   for   mes   algo   while   task   void   temp   

原文地址:https://www.cnblogs.com/SYDevil/p/12051535.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!