![[codevs]1087麦森数 [codevs]1087麦森数](https://image.shishitao.com:8440/aHR0cHM6Ly9ia3FzaW1nLmlrYWZhbi5jb20vdXBsb2FkL2NoYXRncHQtcy5wbmc%2FIQ%3D%3D.png?!?w=700&webp=1)
题目
这个题在noiOJ上是分治专题,这个题包括了很多,求位数,高精度乘,快速幂。
那么单独把这个高精度拿出来做一个自定义函数即可
一、求位数
显而易见,既然是2进制的就是log2X,是10进制就是lgX(值得注意的是,在计算机语言当中lg就是loge)。
二、快速幂
还是老套路,先二进制拆分,用1248的那个来看,把这些都乘起来,最后和高精度结合,下面就是部分代码
while(P)
{ ) mul(ans,tmp); mul(tmp,tmp); P>>=; }
;i<=;++i) ;j<=;++j) c[i+j-]+=(a[i]*b[j]); ;i<=;++i)
{ c[i+]+=c[i]/; c[i]%=; }
}
这里的数组c只是一个临时答案,最后会把c复制给ans。
高精度乘很好理解
_______________* _______________+ _______________+
这就是高精度乘法的思路,那么也没什么难点,不用去除前导0。
下面上答案
#include <cstdio> #include <cmath> #include <cstring> using namespace std; int P; ],tmp[],c[]; void mul(long long a[],long long b[],int f){ memset(c,,sizeof(c)); ;i<=;++i) ;j<=;++j) c[i+j-]+=(a[i]*b[j]); ;i<=;++i){ c[i+]+=c[i]/; c[i]%=; } if(f) memcpy(tmp,c,sizeof(c)); else memcpy(ans,c,sizeof(c)); } int main(){ scanf("%d",&P); printf()))+); ans[]=; tmp[]=; while(P){ ) mul(ans,tmp,); mul(tmp,tmp,); P>>=; } ]) --ans[]; ;i>=;--i){ )) printf("\n"); printf("%lld",ans[i]); } ; }
还有188天初赛, 还有216天复赛。
那是我愿意付诸一生的人,现在却没法拥有。