• TZOJ 5291 游戏之合成(快速幂快速乘)


    描述

    zzx和city在玩一款小游戏的时候,游戏中有一个宝石合成的功能,需要m个宝石才可以合成下一级的宝石(例如需要m个1级宝石才能合成2级宝石)。

    这时候zzx问city说“我要合成A级宝石需要多少个B级的宝石(A>B)。”

    city说:“这数字会好大的。”

    zzx:“没事的,你选择一个数取余数就行了,你只要告诉我余数就好了”

    city:“那就对梅森素数取余好了”

    但最后,由于数字过于大,city又不想手算了,于是想请你帮忙。

    输入

    多组数据,输入到文件结束为止

    每组输入4个正数m,A,B,K,m,A,B为题目描述的意思,K为对第K个梅森素数取余

    数据保证M,A,B不会大于第K个梅森素数(K<10)

    输出

    一个整数为合成A级宝石需要多少个B级的宝石对第K个梅森素数取余的结果

    样例输入

    5 5 1 2
    4 4 1 2

    样例输出

    2
    1

    提示

    1.第一组样例解释:合成5级宝石需要5个4级的宝石,合成5个4级宝石需要25个3级宝石,以此类推,合成5级宝石需要625颗1级宝石,第2个梅森素数为7,625除7余2.

    2.输入输出数据过于庞大,c++输入输出你应该使用scanf和printf,而不是cin和cout

    3.梅森素数是由梅森数而来。所谓梅森数,是指形如2p-1的一类数,其中指数p是素数,常记为Mp 。如果梅森数是素数,就称为梅森素数。

    梅森素数表

    序号

    p

    Mp=(2p)-1

    Mn的位数

    发现时间

    发现者

    1

    2

    3

    1

    古代

    古人

    2

    3

    7

    1

    古代

    3

    5

    31

    2

    古代

    古人

    4

    7

    127

    3

    古代

    古人

    5

    13

    8191

    4

    1456

    无名氏

    6

    17

    131071

    6

    1588

    Cataldi

    7

    19

    524287

    6

    1588

    Cataldi

    8

    31

    2147483647

    10

    1772

    欧拉

    9

    61

    2305843009213693951

    19

    1883

    Pervushin

    10

    89

    618970019642690137449562111

    27

    1911

    Powers

    题意

    输出合成A级宝石需要多少个B级的宝石对第K个梅森素数取余后的值

    题解

    典型的快速乘+快速幂m^(A-B)%f[k],f[k]代表第k个梅森素数

    这题当时是比赛的时候做的题,不会存第9个梅森素数所以没做出来

    这个题有3个坑:

    1.存第9个梅森素数(2305843009213693951LL)

    2.m^(A-B)其中A-B太大会超时(快速幂)

    3.第9个素数相乘超过19位爆int64(快速乘)

    代码

     1 #include<stdio.h>
     2 __int64 multi(__int64 m,__int64 n,__int64 mod){
     3     __int64 ans=0;
     4     while(n){
     5         if(n&1)ans+=m;
     6         m=(m+m)%mod;
     7         m%=mod;
     8         ans%=mod;
     9         n>>=1;
    10     }
    11     return ans;
    12 }
    13 __int64 pow(__int64 a,__int64 n,__int64 mod){
    14     __int64 ans=1;
    15     while(n){
    16         if(n&1)ans=multi(ans,a,mod);
    17         a=multi(a,a,mod);
    18         ans%=mod;
    19         a%=mod;
    20         n>>=1;
    21     }
    22     return ans;
    23 }
    24 int main(){
    25     __int64 f[]={0,3,7,31,127,8191,131071,524287,2147483647,2305843009213693951LL};//存19位最后加LL
    26     __int64 m,a,b,k;
    27     while(scanf("%I64d%I64d%I64d%I64d",&m,&a,&b,&k)!=EOF){
    28         m%=f[k];
    29         printf("%I64d
    ",pow(m,a-b,f[k]));
    30     }
    31     return 0;
    32 }
  • 相关阅读:
    Spring定时
    随记生成验证码
    缅怀过去
    java运行可以执行文件
    随 记
    TLD生成
    IT鸟的回忆录
    梦之物语
    VINSMono
    WIDOWX 250 6DOF
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/8295425.html
Copyright © 2020-2023  润新知