[复习]快速幂加强(快速幂+快速乘) 病毒

题目描述
2015年1月1日,国际卫生组织公布了一种新型病毒CAI,其复制能力极强,会使人的记忆能力严重衰退。

在每 1 秒内,一个病毒会分身出 N 个病毒(本体不计),它们和本体拥有着同样的能力,如果 N=4,在第一秒初有 1 个病毒本体,第一秒末分裂出 4 个,那么第一秒末有 5 个,它们在第二秒末会再分裂 5*4 =20个,那么加上最开始的,第二秒末就有 25 个。

为了抑制这种可怕的病毒,清华大学的医学研究人员经过认真研究这种病毒的基因,发明了一种新型青霉素注射液,能有效的消灭这种病毒。人体只需要注射一次这种青霉素,就可以终身免疫。这种青霉素杀毒的前提是:当病毒的数量必须达到或者超过 P 个(对人体开始有害),药力才会自动发挥作用——瞬间全部消灭 P 个病毒。那么,在第 M 秒末,环境中还有多少病毒呢?(注,第一秒初开始就注射了青霉素)

输入格式
输入数据只有一行,为 3 个整数 N、M 和 P,其含义如题目描述(初始时,只有一只病毒)。

输出格式
输出数据只有一行,为第 M 秒最后剩余的病毒数目。

样例数据1
输入

4 3 3

输出

2

样例数据2
输入

10000 1000 1

输出

0

备注
【样例1说明】
第一秒的病毒分裂出 4 个,加上本体就是 5 个,消灭三个还剩两个。
第二秒的病毒分裂出 2*4=8 个,加上两个本体就是 10 个,药力发挥 3 次,消灭了 9 个,还剩一个。
第三秒剩下的那个分裂出 4 个,加上本体就是 5 个,药力发挥一次消灭三个,还剩两个。

【样列2说明】
只要有 1 个病毒,药力就发挥杀毒功能,显然没有病毒能活下来。

【数据范围】
对于 1/3 的数据:M≤100000;
对于 2/3 数据:1≤N,P≤ 230 ,1≤M≤1152921504606846976;
对于 3/3 数据:1≤N≤ 230 ,1≤P≤ 260 ,1≤M≤1152921504606846976

分析:快速幂模板的加强版,快速乘并不是为了提升速度而是防止直接相乘爆long long。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#include<queue>
#include<set>
using namespace std;

long long getlong()
{
    long long sum=0,f=1;
    char ch;
    for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());
    if(ch=='-')
    {
        f=-1;
        ch=getchar();
    }
    for(;isdigit(ch);ch=getchar())
        sum=(sum<<3)+(sum<<1)+ch-48;
    return sum*f;
}

long long n,m,p;

long long ksc(long long x,long long y)
{
    long long res=0;
    for(;y>=1;y=y>>1,x=(x+x)%p)
        if(y&1)
            res=(res+x)%p;

    return res; 
}

void ksm()
{
    long long ans=1;n=n+1;
    for(;m>=1;m=m>>1,n=ksc(n,n))
        if(m&1)
            ans=ksc(ans,n);
    cout<<ans<<'\n';
}

int main()
{
    freopen("virus.in","r",stdin);
    freopen("virus.out","w",stdout); 

    n=getlong(),m=getlong(),p=getlong();
    ksm();
    return 0;
}

本题结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值