1008: [HNOI2008]越狱
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 5099 Solved: 2207
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)
Source
大意:给N个格子,M种颜色,给这些格子染色,问使这N个格子,存在相邻两个格子颜色相同的方案数
分析:简单明了,简单异常
首先一共有M^N种方式染色
使相邻格子颜色不同的方案有M*(M-1)^(N-1)种(第一位有M种选择,后面每位都只有M-1种选择)
然后相邻格子颜色不相同的方案:M^N - M*(M-1)^(N-1)
最后提醒:注意因为是快速幂取模,所以答案有可能为负数,要修正为正数
综上所述,本题得解
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <iostream> 9 #include <algorithm> 10 #include <map> 11 #include <set> 12 #include <ctime> 13 using namespace std; 14 typedef long long LL; 15 typedef double DB; 16 #define For(i, s, t) for(int i = (s); i <= (t); i++) 17 #define Ford(i, s, t) for(int i = (s); i >= (t); i--) 18 #define MIT (2147483647) 19 #define INF (1000000001) 20 #define MLL (1000000000000000001LL) 21 #define sz(x) ((bnt) (x).size()) 22 #define clr(x, y) memset(x, y, sizeof(x)) 23 #define puf push_front 24 #define pub push_back 25 #define pof pop_front 26 #define pob pop_back 27 #define ft first 28 #define sd second 29 #define mk make_pair 30 inline void SetIO(string Name) { 31 string Input = Name+".in", 32 Output = Name+".out"; 33 freopen(Input.c_str(), "r", stdin), 34 freopen(Output.c_str(), "w", stdout); 35 } 36 37 const LL Mod = 100003; 38 LL N, M; 39 LL All, Impossible, Possible; 40 41 inline void Input() { 42 cin>>M>>N; 43 } 44 45 inline void Multiply(LL &A, LL B) { 46 A = (A*B)%Mod; 47 } 48 49 inline LL Power(LL Basic, LL Tim) { 50 LL Ret = 1; 51 Basic %= Mod; 52 while(Tim) { 53 if(Tim&1) Multiply(Ret, Basic); 54 Multiply(Basic, Basic), Tim >>= 1; 55 } 56 return Ret; 57 } 58 59 inline void Solve() { 60 if(N == 1) { 61 cout<<M<<endl; 62 return; 63 } 64 65 All = Power(M, N); 66 Impossible = Power(M-1, N-1); 67 Multiply(Impossible, M); 68 Possible = All-Impossible; 69 Possible = ((Possible%Mod)+Mod)%Mod; 70 71 cout<<Possible<<endl; 72 } 73 74 int main() { 75 SetIO("1008"); 76 Input(); 77 Solve(); 78 return 0; 79 }
时间: 2024-10-05 20:13:25