//最初实现的版本比lisp写的fact要慢很多(1/5的效率),多次优化后终于比lisp快了。还能怎么提高效率?
// HugeInt.h: interface for the HugeInt class.
#ifndef HUGEINT_H
#define HUGEINT_H
#include<iostream>
#include<vector>
class HugeInt
{
enum {computebound=1000000000,computewidth=9};
typedef unsigned int eletype;
public:
HugeInt();
HugeInt(int);
HugeInt(int,int);
bool operator==(const HugeInt &)const;
HugeInt operator+(const HugeInt &)const;
HugeInt operator*(const HugeInt &)const;
friend std::ostream & operator<<(std::ostream &,const HugeInt &);
private:
std::vector<eletype> m_Buffer;
HugeInt domul(eletype ,int)const;
};
std::ostream & operator<<(std::ostream &,const HugeInt &);
#endif
#include "HugeInt.h"
#include<iomanip>
#include<algorithm>
HugeInt::HugeInt()
{
}
HugeInt::HugeInt(int Value)
{
eletype x(Value);
eletype y=x/computebound;
if(y)
{
m_Buffer.push_back(x%computebound);
m_Buffer.push_back(y);
}
else
{
m_Buffer.push_back(x);
}
}
HugeInt::HugeInt(int size,int value):m_Buffer(size,value)
{
}
bool HugeInt::operator==(const HugeInt &Value)const
{
if(m_Buffer.size()!=Value.m_Buffer.size())return false;
return std::equal(m_Buffer.begin(),m_Buffer.end(),Value.m_Buffer.begin());
}
HugeInt HugeInt::operator+(const HugeInt &Rv)const
{
const HugeInt &Da=(m_Buffer.size()>Rv.m_Buffer.size())?*this:Rv;
const HugeInt &Xiao=(this==&Da)?Rv:*this;
HugeInt Ret(Da.m_Buffer.size()+1,0);
eletype jw=0;
eletype *pos=&Ret.m_Buffer[0];
const eletype *pos1=pos+Xiao.m_Buffer.size();
const eletype *pos2=pos+Da.m_Buffer.size();
const eletype *posda=&Da.m_Buffer[0];
const eletype *posxiao=&Xiao.m_Buffer[0];
for(;pos<pos1;++pos,++posda,++posxiao)
{
*pos=*posda + *posxiao + jw;
jw=0;
if(*pos>computebound)
{
++jw;
*pos-=computebound;
}
}
for(;pos<pos2;++pos,++posda)
{
*pos=*posda+jw;
jw=0;
if(*pos>computebound)
{
++jw;
*pos-=computebound;
}
if(jw==0)
{
++pos;
++posda;
std::copy(posda,posda+(pos2-pos),pos);
pos=const_cast<eletype *>(pos2);
break;
}
}
if(!(jw==0))
{
*pos=jw;
++pos;
}
Ret.m_Buffer.resize(pos-&Ret.m_Buffer[0]);
return Ret;
}
HugeInt HugeInt::domul( eletype x,int y)const
{
if(x==0)return HugeInt();
if(x==1)
{
HugeInt Ret(m_Buffer.size()+y,0);
std::copy(m_Buffer.begin(),m_Buffer.end(),Ret.m_Buffer.begin()+y);
return Ret;
}
HugeInt Ret(m_Buffer.size()+1+y,0);
eletype jw=0;
eletype *pos=&Ret.m_Buffer[0]+y;
const eletype *pos1=pos+m_Buffer.size();
const eletype *pos2=&m_Buffer[0];
unsigned long long tmp;
for(;pos<pos1;++pos,++pos2)
{
tmp=(*pos2)*(unsigned long long)x+jw;
jw=tmp/computebound;
*pos=tmp-jw*computebound;
}
if(!(jw==0))
{
*pos=jw;
++pos;
}
Ret.m_Buffer.resize(pos-&Ret.m_Buffer[0]);
return Ret;
}
HugeInt HugeInt::operator*(const HugeInt &Rv)const
{
HugeInt Ret;
for (int i=0;i<Rv.m_Buffer.size();++i)
{
if(Rv.m_Buffer[i]==0)continue;
Ret=Ret+domul(Rv.m_Buffer[i],i);
}
return Ret;
}
std::ostream & operator<<(std::ostream &out,const HugeInt &Value)
{
int i=Value.m_Buffer.size()-1;
out<<Value.m_Buffer[i];
--i;
for(;i>=0;--i)
{
out<<std::setfill('0')<<std::setw(HugeInt::computewidth)<<Value.m_Buffer[i];
}
return out;
}
#include <iostream>
#include "HugeInt.h"
HugeInt fact(int x)
{
HugeInt ret=1;
if(x<2)return ret;
for(int i=2;i<=x;++i)
{
ret=ret*i;
}
return ret;
}
int main()
{
while(1)
{
int x;
HugeInt tmp;
std::cin>>x;
{
tmp=fact(x);
}
std::cout<<tmp<<std::endl;
break;
}
return 0;
}