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\)最优解

时间计算:我们假设每次分治刚好使左右乘积位数相等,则时间为:\(O(nlog^2n)\)

\[ T(n)=\left\{
\begin{array}{rcl}
2T(\frac{n}{2})+nlogn&& {1<n}\\
1&& {n=1}
\end{array} \right. \]

\(Ex:如何让左右长度更接近\)

数字\(n\)的长度约为\(lg\ n(以10为底的对数函数)\)

\(\because len(\prod_{i=l}^ri)\approx \sum_{i=l}^rlg\ i\approx \int_l^rlg\ x\ dx\)

\(\therefore 我们想要\int_l^{mid}lg\ x\ dx=\int_{mid}^rlg\ x\ dx\)

\(\rightarrow \int_0^llg\ x\ dx+\int_0^rlg\ x\ dx=2\int_0^{mid}lg\ x\ dx\)

\(\because \int lg\ x\ dx=\frac{xlnx-x}{ln10}\)

\(\therefore 我们二分mid,使\frac{mid\ lnmid-mid}{ln10}=\frac{\frac{l\ lnl-l}{ln10}+\frac{r\ lnr-r}{ln10}}{2}\)

\(\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;
}

\(Ex\)版

#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;
const double ln10=log(10);
double g(double x){return (x*log(x)-x)/ln10;}
Array answer(int l,int r){
if(l==r)return change(l);
int mid;
double al=(g(l)+g(r))/2,tl=l,tr=r,am;
while(tl+0.5<=tr){
am=(tl+tr)/2;
if(g(am)<=al)mid=am,tl=am;
else tr=am;
}
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)的更多相关文章

  1. HDU1042(N!)题解

    HDU1042(N!)题解 以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 计算N的阶乘并输出. [题目分析] 题给范围上限是10000,那么毫无疑问是大数题.之前我整理过各种 ...

  2. ACM训练计划建议(转)

    ACM训练计划建议 From:freecode#  Date:2015/5/20 前言: 老师要我们整理一份训练计划给下一届的学弟学妹们,整理出来了,费了不少笔墨,就也将它放到博客园上供大家参考. 菜 ...

  3. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  4. Angular2学习笔记(1)

    Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...

  5. ASP.NET Core 之 Identity 入门(一)

    前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库,负责对用户的身份进行认证,总体来说的话,没有MVC 5 里面那么复杂,因为在MVC 5里面引入了OW ...

  6. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  7. Online Judge(OJ)搭建(第一版)

    搭建 OJ 需要的知识(重要性排序): Java SE(Basic Knowledge, String, FileWriter, JavaCompiler, URLClassLoader, Secur ...

  8. 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑

    阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...

  9. 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成

    阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...

随机推荐

  1. Windows安装与配置—MongoDB

    1,下载安装 打开下载链接:http://dl.mongodb.org/dl/win32/x86_64,选择后缀是2008plus-ssl-3.6.15.zip的版本,32位和64位通用. 2,安装配 ...

  2. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 3

    18.3  PDO的安装 PDO随PHP 5.1版本发行,在PHP 5的PECL扩展中也可以使用.PDO需要PHP 5版本核心面向对象特性的支持,所以它无法在之前的PHP版本中运行.无论如何,在配置P ...

  3. Have a look ^_^

    参考书籍: <重构 改善既有代码的设计 第2版>马丁 福勒著 人民邮电出版社 马丁 福勒的其他著作:<分析模式>,<UML精粹>,<领域特定语言> 目录 ...

  4. 简单探讨一下.NET Core 3.0使用AspectCore的新姿势

    前言 这几天在对EasyCaching做支持.net core 3.0的调整.期间遇到下面这个错误. System.NotSupportedException:"ConfigureServi ...

  5. Spring5源码解析2-register方法注册配置类

    接上回已经讲完了this()方法,现在来看register(annotatedClasses);方法. // new AnnotationConfigApplicationContext(AppCon ...

  6. 解决真机编译出现System.DllNotFoundException: 'libmono-native.so'错误都方法

    1.去掉勾选:使用共享运行时 2 检查android SDK是否安装了NDK 3.使用真机运行编译APK

  7. java基础(15):常用API(Object、String、StringBuffer)

    1. Java的API及Object类 在以前的学习过程中,我们都在学习对象基本特征.对象的使用以及对象的关系.接下来我们开始使用对象做事情,那么在使用对象做事情之前,我们要学习一些API中提供的常用 ...

  8. 反射实体类拼接SQL语句

    实体类基类: using System; using System.Collections.Generic; using System.Linq; using System.Reflection; u ...

  9. Java之IO模型

    首先来看一下同步与异步的概念: 1.同步是指当前端发起一次操作请求时,只有后台执行完所有的代码操作才会给前端返回值. 2.异步是将前端发回的消息加入消息队列,并且立刻给前端返回请求,告诉用户可以离开当 ...

  10. HTTP协议中的Range和Content-Range

    " 琢磨HTTP协议的每一个细节." HTTP协议博大精深,每一个细节都应细细体会. 否则,在协议还原的过程中,你会遇到各种问题. 今天,本文中将对HTTP协议的Range和Con ...