一本通1618越狱

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

#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;
}
View Code

 

posted @ 2019-02-24 09:02  yccdu  阅读(402)  评论(0编辑  收藏  举报