[NOIP2003普及组]麦森数(快速幂+高精度)

Description

形如2^P-1的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果P是个素数,2^P-1不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P=3021377,它有909526位。麦森数有许多重要应用,它与完全数密切相关。
任务:从文件中输入P(1000 < P < 3100000),计算2^P-1的位数和最后500位数字(用十进制高精度数表示)

Input

只包含一个整数P(1000 < P < 3100000)

Output

第一行:十进制高精度数2^P-1的位数。
第2-11行:十进制高精度数2^P-1的最后500位数字。(每行输出50位,共输出10行,不足500位时高位补0)
不必验证2^P-1与P是否为素数。

Sample Input

1
1279

Sample Output

1
2
3
4
5
6
7
8
9
10
11

386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000104079321946643990819252403273640855
38615262247266704805319112350403608059673360298012
23944173232418484242161395428100779138356624832346
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
50138443826029173234888531116082853841658502825560
46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087

题目大意:计算2^P-1的位数和它的最后500位并输出。
1、计算位数:2^P-1的位数为[log10(2^P)]+1==[Plog10(2)]+1
2、计算最后500位:高精度预处理2^i,计算时将P分解成二进制形式,然后相乘,只保留500位
3、网站上的似乎和原题不太一样,原题要求每输出50位换行

倍增快速幂+高精(果然什么东西跟高精扯上就恶心了)

只保留最后500位,前面的直接卡掉

位数可以直接算出来,n进制数M的位数是log(n)M,那么log(10)2^p=p*log(10)2=p*(log(2)/log(10))

1、肯定需要高精度,毕竟500位

2、普通乘法肯定超时,乘法次数*位数

因为位数=plog(10)2=310W*log2

操作次数为=310W

所以普通乘法的复杂度为:n^2,这肯定要炸的不能在炸。 

如果是保留500位,那也是500*310W,也要超,所以这里一定要用到快速幂

本题分两问,第一问求位数,可以证明:当x有n位时,必有10^(n-1)<=x<10^n(如x有3位时必有100=10^2<=x<1000=10^3),取常用对数,n-1<=lgx<n,即lgx的整数部分是n-1,也就是说数x的位数是lg(x)的整数部分+1。故欲求x的位数只需求floor(log10(x)+1).

然后第二问是去掉了取模运算、用上高精度的快速幂:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 void mul(int x[],int y[]);
 4 int main()
 5 {
 6     long p;
 7     int num=0;
 8     int ans[501]={0},a[501]={0},i;
 9     freopen("mason.in","r",stdin);
10     freopen("mason.out","w",stdout);
11     scanf("%ld",&p);
12     //第一问ok
13     num=(int)floor(p*log10(2)+1);
14     printf("%d\n",num);
15
16     /*快速幂求2^p,同时用高精度乘法*/
17     ans[1]=1; a[1]=2;
18     while(p>0)
19     {
20         if(p&1)      //if(p%2==1)
21             mul(ans,a);
22         p=p>>1;      //p=p/2;
23         mul(a,a);    //a*a -> a
24     }
25     ans[1]-=1;     //这个地方其实直接减1会有bug。当ans[1]为0的时候是错误的结果。所以可以采用下面的方法减1。但是对这个题目而言,2^p-1必然是奇数,也即个位是不可能为0。(ans[1]不会为0.)
26     /*for(i=1;i<=500;i++)
27     {
28         if(ans[i]>0) {ans[i]--;break;}
29     }
30     for(;i>=1;i--) ans[i]=9;*/
31     for(i=500;i>0;i--) {printf("%d",ans[i]); if((i-1)%50==0) printf("\n");}
32     printf("\n");
33     return 0;
34 }
35 void mul(int x[],int y[])
36 {
37     /*   x*y->x   */
38     int tmp[520]={0},lx=500,ly=500,i,j,len;  //tem[]一定要清零。
39     //memset(tmp,0,sizeof(tmp));
40     while(x[lx]==0&&lx>0) lx--; //计算x首位位置
41     while(y[ly]==0&&ly>0) ly--; //计算y首位位置
42     len=lx+ly;
43     for(i=1;i<=ly;i++)
44        for(j=1;j<=lx;j++)
45            if(i+j-1<=500) tmp[i+j-1]+=y[i]*x[j];   //if语句是保证只保留500位
46     for(i=1;i<=500;i++)
47     {
48         tmp[i+1]+=tmp[i]/10; //把进位的值加到高位
49         tmp[i]%=10;
50         /*if(i<500&&tmp[i+1]==0)
51         {len=i; break;}*/  //这个地方没理解其用意,似乎只是优化循环次数。但len没有使用的机会,所以干脆删除掉比较好。
52     }
53     for(i=500;i>0;i--) x[i]=tmp[i];  //把结果复制到x数组
54 }

转载于:https://www.cnblogs.com/Renyi-Fan/p/8142671.html

[NOIP2003普及组]麦森数(快速幂+高精度)相关推荐

  1. 信息学奥赛一本通 1925:【03NOIP普及组】麦森数 | OpenJudge NOI 4.4 1708:麦森数 | 洛谷 P1045 [NOIP2003 普及组] 麦森数

    [题目链接] ybt 1925:[03NOIP普及组]麦森数 OpenJudge NOI 4.4 1708:麦森数 洛谷 P1045 [NOIP2003 普及组] 麦森数 [题目考点] 1. 高精度 ...

  2. Codevs_P1087 麦森数(快速幂+分治)

    麦森数(Mason.cpp) [问题描述]形如2P-1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2P-1不一定也是素数.到1998年底,人们已找到了37个麦森数.最大的 ...

  3. 高精度:麦森数*(洛谷P1045)

    P1045 [NOIP2003 普及组] 麦森数 解析 看似只是正常的一个高精 然而 暗藏杀机 一开始随手那么一写 ... (即使用了快速幂)时间复杂度过于感人 后来我们发现: 第一问位数的计算不必真 ...

  4. 【codevs1087NOIP2003】麦森数,高精度+对数+快速幂

    麦森数 2003年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 形如2P-1的素数称为麦森数,这时P ...

  5. [蓝桥杯][算法训练VIP]麦森数(Java大数+快速幂)

    题目描述 形如2p-1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2p-1不一定也是素数.到1998年底,人们已找到了37个麦森数.最大的一个是P=3021377,它有9 ...

  6. (快速幂算法+高精度)洛谷P1045 麦森数

    前言   故事的最后,让我们以一道十分经典的题目--<麦森数>来结尾.接受现实吧,总会有我们没准备过的高精度运算出现.我们固然可以提前把高精度的快速幂模板也准备好,但是总会有百密一疏的时候 ...

  7. 【9704】【9109】麦森数

    Time Limit: 3 second Memory Limit: 2 MB [问题描述] 形如2p-1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2p-1不一定也是素 ...

  8. 麦森数(洛谷-P1045)

    题目描述 形如 2^{P}-1 的素数称为麦森数,这时 P 一定也是个素数.但反过来不一定,即如果 P 是个素数, 2^{P}-1 不一定也是素数.到1998年底,人们已找到了37个麦森数.最大的一个 ...

  9. 蓝桥杯 ALGO-26 算法训练 麦森数

    问题描述 形如2P-1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2P-1不一定也是素数.到1998年底,人们已找到了37个麦森数.最大的一个是P=3021377,它有9 ...

最新文章

  1. Linux中的用户及文件权限管理总结
  2. ViSP中AprilTag的实时识别与定位
  3. 3、假设有一个对象数组,想根据某个对象属性对数组进行排序时
  4. uc通讯不成功php版本过高,Ucenter通信失败排查方法
  5. 解决PyInstaller打包程序exe在win7运行异常问题(OSError: [WinError 87] 参数错误、Error loading Python DLL python39.dll等)
  6. zookeeper安装和使用
  7. 2009.12.9.工作日记
  8. 自己做的一个水印生成类
  9. 正则表达式限制文本框内容
  10. 查看Linux内核版本命令
  11. JS AES加密解密实现
  12. 常见的四种硬盘接口介绍
  13. java excel 透视_在Java中用Excel创建数据透视表和数据透视图
  14. 如何用java实现一个p2p种子搜索(4)-种子获取
  15. 大言不惭 swank? talk about sth or speak too confidently
  16. 《深度学习之美》第3章
  17. java-php-net-python-税务申报系统ssh计算机毕业设计程序
  18. 广州大学机器学习与数据挖掘实验三
  19. 定个可以实现的小目标
  20. 基于C++的Qt网络编程——基于 IP 多播的网络会议程序

热门文章

  1. git分布式版本管理系统和github平台
  2. UnityShader27:屏幕雾效
  3. opencv 基本绘图功能 画直线 画圆 给图像添加文字等
  4. [python] 字典:按key排序或按value排序
  5. c#zip压缩解压缩全解
  6. ajax只请求一次,关于ajax的请求只处理一次的问题
  7. 设计模式01-模板设计模式
  8. Nginx编译./configure翻译
  9. w2金融股票分析— matplotlib库
  10. 面试之mybatis和hibernate的区别