输入输出样例
输入:
1279
输出:
386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000104079321946643990819252403273640855
38615262247266704805319112350403608059673360298012
23944173232418484242161395428100779138356624832346
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
50138443826029173234888531116082853841658502825560
46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087
很明显,拿到这道题,要结局的由两部分。第一部分是求2的n次幂-1的位数。易得,2的n次幂-1的位数与2的n次幂的位数相同(因为2的n次结尾一定不会带0),因此,计算位数只需计算2的n次所得的数字的位数即可。
计算方法如下:
易知,10的n次幂的数字的位数为n,只需做一些小小的改动,将2的n次幂放在10的指数位置上即可,2 ^ n 也作 10 ^ log 10 ( 2 ^ n ) ,可化简为:10 ^ (log 10 ( 2 ) * n),因此,所求位数即为 :log 10 ( 2 ) * n(c++的cmath头文件自带计算log10()的函数)。
解决了位数问题,下面来解决高精度计算的问题。
显而易见,本题想要不爆TLE,需要使用快速幂(2的n次幂,显而易见)。
快速幂的原理又是什么呢?您可以自行前往CSDN搜索,CSDN中不乏优秀的博主,比以下笔者的见解强上千倍万倍,笔者的思路,亦是从其他博文学习而来的。
举个例子,计算 3^10 ,可以拆分为:3333333333,简单地使用循环,需要计算10次,看似很快,但当n的值无穷大时,循环的暴力做法便失效了。因此,我们另辟蹊径,拿出一个33,结果为9,那么这个计算便简化为 3 ^ 8 * 9 ,然而,指数只是减小了2,仍不能避免多次的计算,因此,换个思路,我们应想法设法地减小指数,而不是将多次操作不断分割。若换成(3*3)^ 5,即9 ^ 5,这样计算的时间直接减半,而此时,由于指数变为奇数,不能再进行 /2 的指数分割,便提出一个9,使指数变为4次,再进行分割运算。因此,到最后,仅需计算9×6561(9 ^ 4的结果),即可得到最终答案。下面是快速幂的代码实现:
typedef int ElemType;
ElemType fastPower(ElemType base,ElemType power){
//base代表底数,power代表指数
ElemType result = 1;
while( power > 0 ){