BZOJ_1008 越狱(快速幂)

http://www.lydsy.com/JudgeOnline/problem.php?id=1008

Description

  监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种。如果
相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱

Input

  输入两个整数M,N.1<=M<=10^8,1<=N<=10^12

Output

  可能越狱的状态数,模100003取余

Sample Input

2 3

Sample Output

6

HINT

  6种状态为(000)(001)(011)(100)(110)(111)

 

从题目里可以知道,N个房间M个宗教,可能产生的所有状态为A=N^M,要求出所有可能越狱的状态可能比较难,不如使用逆向思维,求所有不可能的越狱状态,可知只要相邻的房间宗教不同即可,故所有的不可能越狱状态为B=M*(M-1)*(M-1)...(M-1)=M*(M-1)^(N-1),那么答案就是A-B了,写个快速幂函数求出A,B即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
/*ll quickpower(ll m,ll n)//简写版本
{
    if(n==0) return 1;
    ll temp=quickpower(m,n>>1);// n>>1 == n/2  n的二进制右移几位就是除以2的n次方 
    temp=temp*temp%100003;
    if(n&1) temp=temp*m%100003;// n&1也就是取n的二进制最低位,判断n是否为奇数,是则为1 
    return temp%100003;
}*/
ll quickpower(ll m,ll n)//更容易看懂的版本
{
    if(n==0) return 1;
    else
    {
        while((n&1)==0)
        {
            n>>=1;
            m=m*m%100003;
        }
    }
    int temp=m;
    n>>=1;
    while(n!=0)
    {
        m=m*m%100003;
        if((n&1)!=0)    temp=temp*m%100003;
        n>>=1;
    }
    return temp;
 } 
int main()
{
    ll m,n;
    cin>>m>>n;
    m%=100003;
    ll ans=quickpower(m,n);
    ans-=(m*quickpower(m-1,n-1))%100003;
    cout<<(ans+100003)%100003<<endl;
    return 0;
 } 

 

posted @ 2017-03-03 18:25  Ying_Zhixin  阅读(165)  评论(0编辑  收藏