1618:越狱
时间限制: 1000 ms 内存限制: 524288 KB【题目描述】
原题来自:HNOI 2008
监狱有连续编号为 1 到 n 的 n 个房间,每个房间关押一个犯人。有 m 种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。求有多少种状态可能发生越狱。
【输入】
输入两个整数 m 和 n。
【输出】
可能越狱的状态数,对 100003 取余。
【输入样例】
2 3
【输出样例】
6
【提示】
样例说明
所有可能的 66 种状态为:{0,0,0},{0,0,1},{0,1,1},{1,0,0},{1,1,0},{1,1,1}。
数据范围与提示:
对于全部数据,1≤m≤108,1≤n≤1012 。
sol:结论题+1
好像直接统计越狱方案有点难,于是用(总情况数-不会越狱的情况数),
总情况数就是 mn
不会越狱的情况数就是:任意相邻两个都不一样,显然第一个有m中情况,第二个确保不一样就是m-1,第三个和第二个不一样m-1种,类推
所以就是m*m-1n-1
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } inline void writeln(ll x) { write(x); putchar('\n'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) writeln(x) const ll Mod=100003; ll n,m; inline ll Ksm(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() { R(m); R(n); if(n<2)return 0*puts("0"); Wl(((Ksm(m,n)-m*Ksm(m-1,n-1)%Mod)%Mod+Mod)%Mod); return 0; }