高精度之关于高精度的其他问题
2017-05-31 20:09
239 查看
一.高精度阶乘
高精度阶乘其实就是加法的进阶版,朴素的版本可以模拟阶乘过程,首先阶乘的数据必定不会太大,所以可以持续用高精度乘以低精度进行计算。但是问题是当n!稍微大一点就会导致运行超时。所以可以把n!拆成n*(n-1),(n-2)*(n-3)或是更少的组进行计算,最后再采用高精度乘以高精度合并结果。
二.万进制高精度
当给出的数据位数很大时带来的问题是数组可能必须开到很大并且相应的效率也会降低,所以我们希望让数组的一个位置存储更多的位数,并且考虑到数组中元素大小的限制,一个位置存四位数是最理想的,这也就是我们说的万进制高精度。当然对于普通的高精度加法和减法,存储的位数可以相应扩大。代码实现起来和普通高精度差不多,只是在取出元素时多取出几位,并且进位改变一下就可以实现。当然我个人认为对于NOIP竞赛来说普通的高精度就足够了,所以我没有再去实现代码。
三.高精度幂
考到算我输首先要介绍一下普通的快速幂算法,其实是利用了反复平方加速的技术。
例如当N=5时,我们可以
(1)a*a=a^2
(2)a^2*a^2=a^4
(3)a^4*a=a*5
这样只要成三次就可以了,对应的当N增大时,省下的时间会更多。
实际编程可以采用降幂的方法,即a^N=(a^2)^N/2.代码片段如下,
其中函数plus(x,y,z)表示将x*y的值赋值给ans,ans为最终的结果。
ans=1; while(N>1) { if(N&1 == 1)//如果为奇数 plus(ans,a,ans);//将多出来的一个a乘到ans plus(a,a,a);//算出来的a^2的值给a N=N>>1;//N=N/2 ,如果a变成了a^2,那么只需要再乘N/2个a就行了 } plus(ans,a,ans);//还有因为N是奇数乘过来的数
对应的转换为高精度问题时只需将plus改为高精度,并将a和ans的存储方式改为数组。这个时候会有一个问题影响到程序的效率,就是当计算ans乘以a的值时,我们可能会将计算的值存到一个临时数组里,计算完后再把临时数组里的数存回ans,这必然会拉低速度,所以我们其实可以全程采用一个指针指向实际的ans数组,每次计算结束后,交换指针地址。注意别忘了每次把“临时数组”腾空。
但是对于指针真的把握不好,所以建议开一个二维数组,然后持续滚动第一维。
还有就是,开始的时候我以为下面这段的思想也是快速幂:
inline long long add(int a,int N) { if(N<1) return 1; int up=1; if( N%2 ) { up=a; } return (add(a,N/2)*add(a,N/2)*up)%k;//重复计算add(a,N/2) }
但是后来才发现,快速幂是将通过将a的值扩大做到对计算进行降幂,这样原来需要乘很多次a但是我只是对a的值扩大了一次就可以少乘很多次,这样就节省了时间。而上面的这段代码实质上是一个拆分问题的过程,它只是把问题拆开,分开算,而没有进行任何的优化,所以时间复杂度和普通幂运算是一样的。
四.总
9f72
结
这些问题都是建立在普通高精度之上的,所以对于基础的问题一定要掌握。
相关文章推荐
- 关于sql备份到其他服务器的问题
- 关于语法运用的一些其他问题
- 关于win7部署iis后,局域网的其他用户不能访问的问题。
- 关于EasyUI 其他问题的解决方式先收藏,后续写demo
- 关于pager-taglib参数和其他url参数混合使用问题。
- 关于FLEX RSL及其他问题
- 关于Zion真实性问题的图文分析及其他 V1.06
- 关于Win7/Vista下IE保护模式下与其他进程间通信的问题
- 关于Eclipse3.3中内容助手不是Alt+/的问题解答,以及它的一些其他新特性
- 关于html中a标签需要传不确定参数,又有其他属性时出现的问题
- 关于语法运用的一些其他问题
- 关于其他视频文件向.flv文件转换的问题
- 关于sql备份到其他服务器的问题
- [拦截器]关于拦截方法调用其他内部方法无法被拦截问题的解决
- 一个关于VS2008在其他未安装VS2008的电脑上无法运行编译的程序的问题 收藏
- 关于语法运用的一些其他问题
- 向大家请教一个关于sharepoint2003的问题,如何使一个Custom List in Datasheet View中某个field从其他list抽取数据当显示时?
- 理顺 JavaScript (6) - 关于字符串的其他问题
- 关于语法运用的一些其他问题