D——简单的容斥+快速幂
Description
有n个人依次排队打饭,有m种饭菜可以选择,每个人可能选择其中一种,如果相邻排队的人打的菜一样,那么就会影响彼此吃饭的心情,求这个队伍中有人被影响心情的状态数,对100003取余。
思路
直接考虑有人被影响心情的方案数显然有些困难,但容易发现总方案数和没有人被影响心情的方案数更容易计算,我们就可以考虑容斥,用总方案数减去不合法的方案数,得到合法的方案数。
考虑队伍里的n个人,每个人都有m种选择,显然总方案数为
m
n
m^n
mn。
考虑没有人被影响心情的方案数,第一个人可以随意选择m种,而第二个人不能与第一个人相同,因此只能选m-1种,而第三个人只需与第二个人不同,因此能选择m-1种,以此类推,方案数显然为
m
∗
(
m
−
1
)
n
−
1
m*(m-1)^{n-1}
m∗(m−1)n−1。两个数都可以用快速幂轻松算出来,最后相减即可。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll mod=100003;
ll n,m;
ll ksm(ll a,ll p)
{
ll pro=1;
while(p)
{
if(p&1) pro=(pro*a)%mod;
p>>=1;
a=(a*a)%mod;
}
return pro;
}
int main()
{
scanf("%lld%lld",&m,&n);
ll tot=ksm(m,n),fal=(ksm(m-1,n-1)*m)%mod;
ll tru=(tot-fal+mod)%mod;//因为减法可能减出负数,因此要加上一个mod
printf("%lld",tru);
return 0;
}