越狱(简单组合+快速幂)
1008: [HNOI2008]越狱
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 8045 Solved: 3437
[Submit][Status][Discuss]
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)
//公式很简单 M^N - M * (M-1)^(N-1)
//然后就是快速幂就解即可
1 //快速幂 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 const int mod=100003; 6 long long hanshu(long long a,long long b) 7 { 8 long long ans=1; 9 a%=mod; 10 while(b) 11 { 12 if(b%2==1) ans=ans*a%mod; 13 b/=2; 14 a=a*a%mod; 15 } 16 return ans; 17 } 18 int main() 19 { 20 long long m,n; 21 scanf("%lld%lld",&m,&n); 22 long long ss=(hanshu(m,n)-m*hanshu(m-1,n-1)+mod)%mod; 23 printf("%lld\n",ss); 24 return 0; 25 }
首先我不知道快速幂做的。。384ms
1 #include <stdio.h> 2 #include <math.h> 3 4 typedef long long LL; 5 const int mod = 100003; 6 7 int main() 8 { 9 LL n,m; 10 while (scanf("%lld%lld",&m,&n)!=EOF) 11 { 12 if (n==1)//还好老子机智 13 { 14 printf("0\n"); 15 continue; 16 } 17 LL ans; 18 int i; 19 //公式很容易想到 M^N-M*(M-1)^(N-1) 20 //关键是怎么实现 21 int n_sq =sqrt(n*1.0); 22 LL temp=1; 23 LL t = m%mod; 24 for (i=0;i<n_sq;i++) 25 { 26 temp*=t; 27 temp%=mod; 28 } 29 t=temp; 30 int k=n/n_sq; 31 for (i=0;i<k-1;i++)//自己算 1 32 { 33 temp*=t; 34 temp%=mod; 35 } 36 int las = n-k*n_sq; 37 t=m%mod; 38 for (i=0;i<las;i++) 39 { 40 temp*=t; 41 temp%=mod; 42 } 43 ans=temp; 44 //*******分割线**********//* 45 //下面要注意细节 N-1 46 temp=1; 47 t =(m-1)%mod; 48 n_sq=sqrt((n-1)*1.0); 49 for (i=0;i<n_sq;i++) 50 { 51 temp*=t; 52 temp%=mod; 53 } 54 55 t=temp; 56 k=(n-1)/n_sq; 57 for (i=0;i<k-1;i++)//自己算 1 58 { 59 temp*=t; 60 temp%=mod; 61 } 62 las = (n-1)-k*n_sq; 63 t=(m-1)%mod; 64 for (i=0;i<las;i++) 65 { 66 temp*=t; 67 temp%=mod; 68 } 69 t=m%mod; 70 temp*=t; 71 temp%=mod; 72 73 ans+=mod; 74 ans-=temp; 75 ans%=mod; 76 printf("%lld\n",ans); 77 } 78 return 0; 79 }