问题描述:
监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱。
输入:
输入两个整数M,N.1<=M<=10^8,1<=N<=10^12
输出:
可能越狱的状态数,模100003取余
例子输入:
2 3
例子输出:
6
6种状态为(000)(001)(011)(100)(110)(111)
思路:
所有的可能的情况数为:m^n,不发生越狱的情况数为:m*(m-1)^(n-1),所以发生越狱的情况数为:m^n-m*(m-1)^(n-1),所以答案为:(m^n-m*(m-1)^(n-1))%mod。注意:1. 取模;2.快速幂
1.取模运算
1)(m^n-m*(m-1)^(n-1))%mod
= (m*(m^(n-1)-(m-1)^(n-1)))%mod
= ((m%mod)*((m^(n-1)-(m-1)^(n-1))%mod)))%mod (3)
=((m%mod)*((m^(n-1)%mod)-((m-1)^(n-1)%mod)+mod)%mod))%mod (2)
令:m^(n-1)%mod=quick_power(m,n-1) (m-1)^(n-1)%mod=quick_power(m-1,n-1)
=((m%mod)*((a-b+mod)%mod))%mod
=m*((a-b+mod)%mod)%mod%mod (6)
=m*((a-b+mod)%mod)%mod
2)运算规则
-
(a + b) % p = (a % p + b % p) % p (1)
-
(a - b) % p = (a % p - b % p) % p (2)
-
(a * b) % p = (a % p * b % p) % p (3)
-
a ^ b % p = ((a % p)^b) % p (4)
-
((a+b) % p + c) % p = (a + (b+c) % p) % p (5)
-
((a*b) % p * c)% p = (a * (b*c) % p) % p (6)
-
(a + b) % p = (b+a) % p (7)
-
(a * b) % p = (b * a) % p (8)
2.快速幂取模
2.快速幂取模
先讨论无需取模的
当b为偶数时:ab=a(b/2)*2=(a2)b/2
当b为奇数时:ab=a*ab-1=a*(a2)(b-1)/2
例如:210=(22)5=(22)*[(22)2]2
211=2*(22)5=2*(22)*[(22)2]2
归纳总结得到:
当指数大于1时,若为偶数,则将指数除以2,底数平方
若为奇数,则先提出一个为底数的系数(可直接把该系数乘进ans中),所以指数减1,然后再按照偶数的办法做
不断迭代下去,当指数为1时,则直接得出答案
最后只要将每次相乘时取模即可,时间复杂度O(log2b)
快速幂取模代码:
inline int mi(int a,int b)
{
int ans=1;
while (b)
{
if (b&1) ans=ans*a%mo;
b>>=1;
a=a*a%mo;
}
return ans;
}
综上,该题的代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=100003;
ll n,m;
ll quick_power(ll x,ll y){
ll ans=1;
while(y){
if(y&1) ans=(ans*x)%mod;
x=(x*x)%mod;
y>>=1;
}
return ans;
}
int main(){
scanf("%lld%lld",&m,&n);
printf("%lld\n",m*((quick_power(m,n-1)-quick_power(m-1,n-1)+mod)%mod)%mod);
return 0;
}
先讨论无需取模的
当b为偶数时:ab=a(b/2)*2=(a2)b/2
当b为奇数时:ab=a*ab-1=a*(a2)(b-1)/2
例如:210=(22)5=(22)*[(22)2]2
211=2*(22)5=2*(22)*[(22)2]2
归纳总结得到:
当指数大于1时,若为偶数,则将指数除以2,底数平方
若为奇数,则先提出一个为底数的系数(可直接把该系数乘进ans中),所以指数减1,然后再按照偶数的办法做
不断迭代下去,当指数为1时,则直接得出答案
最后只要将每次相乘时取模即可,时间复杂度O(log2b)
快速幂取模代码:
inline int mi(int a,int b)
{
int ans=1;
while (b)
{
if (b&1) ans=ans*a%mo;
b>>=1;
a=a*a%mo;
}
return ans;
}
综上,该题的代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=100003;
ll n,m;
ll quick_power(ll x,ll y){
ll ans=1;
while(y){
if(y&1) ans=(ans*x)%mod;
x=(x*x)%mod;
y>>=1;
}
return ans;
}
int main(){
scanf("%lld%lld",&m,&n);
printf("%lld\n",m*((quick_power(m,n-1)-quick_power(m-1,n-1)+mod)%mod)%mod);
return 0;
}