hdu 3003 pupu ( (题目易混淆概念、详解) 二分快速幂 )

14 篇文章 0 订阅
4 篇文章 0 订阅

题目大意:

某生物成年的标志是身上的所有皮肤都从不透明变成过透明至少一次,不是同时变成透明才算。(= =!)

也就是求最里一层皮肤变成透明的天数(最里一层皮肤要变成透明,必须外面其他所有的皮肤都同时透明才行)。

一开始没理解这里,总是不明白样例。

理解后,就可以推导了。

所以,请分清【前n层皮肤同时为透明】和【第n层皮肤变为透明(即前n层皮肤都变透明"过”)】

接下来用total[n]、ans[n}分别表示【前n层皮肤同时为透明的天数】和【第n层皮肤变为透明的天数】

(ans[n]即为题中所求)

 

(举一个有4层皮肤的pupu为例,+表示不透明,  -表示透明)

第一天       第二天    第三天    第四天    第五天   第六天   第七天   第八天    第九天

    +                  -            +              -            +            -            +            -               +

    +                 +             -              -            +           +            -             -               +

    +                 +            +             +            -             -            -             -               +

    +                 +            +             +            +           +            +            +               -

 

有ans[1]=total[1]=2

ans[2]=3  total[2]=4

ans[3]=5 total[3]=8

ans[4]=9

可以看到要使第n层皮肤变透明,必须要前n-1层同时为透明,然后第二天第n层皮肤就会变为透明,同时前n-1层皮肤变成不透明

即有ans[n]=total[n-1]+1----------------------------------------1

 

而要使前n层皮肤同时为透明,则必须第n层皮肤变成透明,然后前n-1层同时为透明,由于第n层皮肤变成透明的那一天,也就是前n-1层皮肤同时为透明的过程的第一天

即有total[n]=ans[n]+total[n-1]-1---------------------------------------2

 

由1式代入2式可得total[n]=total[n-1]*2,又total[1]=2

所以total[n]=2^n

所以ans[n]=total[n-1]+1=2^(n-1)+1

 

下面是采用二分来求取高次幂

 

#include <cstdio>
#include <algorithm>

using namespace std;

long long pow(long long n,long long m)
{
    if(!m)
        return 1;
    if(m==1)
        return 2;
    long long ans;
    ans=pow(n,m/2)%n;
    ans=ans*ans%n;
    if(m%2==1)
        ans=ans*2%n;
    return ans;
}
int main()
{
    long long  n,ans;
    while(scanf("%I64d",&n)&&n)
    {
        ans=(pow(n,n-1)+1)%n;
        printf("%I64d\n",ans);
    }
}

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值