测试地址:越狱
做法:本题需要用到快速幂。
考虑到求能使犯人越狱的序列数量太难,于是反过来求不能使犯人越狱的序列数量。我们令
f(i,j)
为前
i
个人中,最后一个人信宗教
f(i,j)=∑k≠jf(i−1,k)
边界条件为
f(1,j)=1(1≤j≤m)
,题目要求的序列个数为
mn−∑mj=1f(n,j)
。
看到
n
和
g(i)=(m−1)g(i−1)
边界条件为
g(1)=1
,题目要求的序列个数为
mn−m×g(n)
。
注意到
n
还是太大,其实这里已经非常明显了,
以下是本人代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define mod 100003
using namespace std;
ll n,m;
ll power(ll a,ll b)
{
ll s=1,ss=a%mod;
while(b)
{
if (b&1) s=(s*ss)%mod;
b>>=1;ss=(ss*ss)%mod;
}
return s;
}
int main()
{
scanf("%lld%lld",&m,&n);
printf("%lld",((power(m,n)-m*power(m-1,n-1))%mod+mod)%mod);
return 0;
}
本文介绍了一种使用快速幂算法解决特定组合计数问题的方法。通过对问题进行逆向思考,将难以直接解决的问题转化为求解不能使犯人越狱的序列数量。通过定义状态转移方程,并利用快速幂算法高效求解最终答案。
725

被折叠的 条评论
为什么被折叠?



