【容斥原理+快速幂】[HNOI2008]越狱
题目描述
监狱有连续编号为 1…N的 N 个房间,每个房间关押一个犯人,有 M 种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱。
输入输出格式
输入格式:
输入两个整数
M,N
M
,
N
输出格式:
可能越狱的状态数,模 100003 取余
输入输出样例
输入样例#1: 复制
2 3
输出样例#1: 复制
6
说明
6种状态为(000)(001)(011)(100)(110)(111)
1<=M<=10^8,1<=N<=10^12
分析:本来开始我用的DP,后来发现时间复杂度太大,换了一种思路,发现有重复(反正都是错的就不具体说是什么错误了),但是在我上学的路上,突然发现还有一个叫容斥原理的:可能越狱的状态数=总状态数-不可能越狱的状态数,将两个式子表示出来就好了。
总状态数:m^n。这个很容易得出,一共有n个房间,每个房间有m种选择
不可能越狱的状态数:m*(m-1)^(n-1)。假设第一个房间的人信仰的宗教是a(1<=a<=m),如果第二个人信仰的宗教b满足条件(1<=b<=m&&b!=a),那么对于这两个房间的人就不会越狱,同理,第三个房间信仰的宗教c满足条件(1<=c<=m&&c!=b)就不会越狱…以此类推,一共有(n-1)个房间,每个房间有(m-1)种选择,a又有m种选择。
答案:m^n-m*(m-1)^(n-1)
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll m,n;
inline ll quickpow(ll a,ll b,ll q)
{
ll ans=1;
while(b)
{
if(b&1) ans=ans*a%q;
a=a*a%q;
b>>=1;
}
return ans;
}
int main()
{
scanf("%lld%lld",&m,&n);
if(n==1)
{
printf("0");
return 0;
}
printf("%lld",(quickpow(m,n,100003)%100003-m*quickpow(m-1,n-1,100003)%100003+100003)%100003);
return 0;
}
谢谢
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构