【日常学习】【高精快速幂】codevs1087 麦森数题解

46 篇文章 0 订阅
20 篇文章 0 订阅

题目描述 Description

形如2P-1的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果P是个素数,2P-1不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P=3021377,它有909526位。麦森数有许多重要应用,它与完全数密切相关。

任务:从文件中输入P1000<P<3100000),计算2P-1的位数和最后500位数字(用十进制高精度数表示)

输入描述 Input Description

文件中只包含一个整数P1000<P<3100000

输出描述 Output Description

第一行:十进制高精度数2P-1的位数。

2-11行:十进制高精度数2P-1的最后500位数字。(每行输出50位,共输出10行,不足500位时高位补0

不必验证2P-1P是否为素数。

样例输入 Sample Input

1279

样例输出 Sample Output

386

00000000000000000000000000000000000000000000000000

00000000000000000000000000000000000000000000000000

00000000000000104079321946643990819252403273640855

38615262247266704805319112350403608059673360298012

23944173232418484242161395428100779138356624832346

49081399066056773207629241295093892203457731833496

61583550472959420547689811211693677147548478866962

50138443826029173234888531116082853841658502825560

46662248318909188018470682222031405210266984354887

32958028878050869736186900714720710555703168729087

显而易见是一个裸的快速幂高精 第一次写 无论是过程还是输出都遇到了很多问题 感谢里奥神犇不吝赐教 

尤其要注意的是 数组复制 一维数组的传递

时间紧迫直接写上代码

//codevs1087 ÂóÉ­Êý ¸ß¾«+¿ìËÙÃÝ
//copyright by ametake
#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       

using namespace std;

const int maxn=100+10;
const int power=5;
const int base=100000;
long long a[maxn],ans[maxn],c[maxn];

void multi(long long *a,long long *b)
{
    memset(c,0,sizeof(c));
    int len1=a[0];
    int len2=b[0];
    c[0]=min((long long)100,a[0]+b[0]-1);
    for (int i=1;i<=len1;i++)
    {
        for (int j=1;j<=min(len2+i-1,100-i+1);j++)
        {
            c[i+j-1]+=a[i]*b[j];
            c[i+j]+=c[i+j-1]/base;
            c[i+j-1]%=base;
        }
    }
    if (c[c[0]+1]) if (c[0]<100) c[0]++;
}

void print(long long *a)
{
    int cnt=0;
    for (int i=100;i>0;i--)
    {
        cnt++;
        printf("%05lld",a[i]);
        if (cnt%10==0) printf("\n");
    }
    return;
}


int main()
{
    int p;
    scanf("%d",&p);
    printf("%d\n",int(p*log10(2)+1));
    a[0]=1;
    a[1]=2;
    ans[0]=1;
    ans[1]=1;
    while (p)
    {
        if (p&1==1)
        {
            multi(ans,a);
            memcpy(ans,c,sizeof(c));
        } 
        multi(a,a);
        memcpy(a,c,sizeof(c));
        p>>=1;
    }
    ans[1]-=1;
    print(ans);
    return 0;
} 

/*
ÏÈдһ¸öÆÕ¾©¿ìËÙÃÝ= =
´«½øÀ´Èý¸öÊý a,b,c
ÉèÒ»¸öans=1;
while (b)
{
    if (b & 1 == 1) ans*=a;
    a*=a;
    b>>=1;
} 
*/

      
      
     
     
    
    
   
   

——野哭千家闻战伐,夷歌数处起渔樵


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值