[BZOJ1008][HNOI2008]越狱
来源:互联网 发布:淘宝首页源代码下载 编辑:程序博客网 时间:2024/06/05 11:43
提交地址
Description
监狱有连续编号为1…N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱
Input
输入两个整数M,N.1<=M<=10^8,1<=N<=10^12
Output
可能越狱的状态数,模100003取余
Sample Input
2 3
Sample Output
6
HINT
6种状态为(000)(001)(011)(100)(110)(111)
思路:
我们弄一个抽象的题意:
有n个盘子,m种荔枝。
每个盘子放一个荔枝,相邻的盘子荔枝种类一样,求方案数。
1<=M<=10^8,1<=N<=10^12
答案模100003
第一个盘子能放m种荔枝,那么第二个盘子呢???
为了不与第一个盘子的荔枝重复,第二个盘子只能放m-1种荔枝。
第三个盘子呢?
为了不与第二个盘子的荔枝重复,第三个盘子也是放m-1种荔枝?
求可能搭配出的方案数。
这不就是小学奥数上的乘法原理嘛!!!
于是我们得出
num=m * (m-1)^(n-1)
这是合法的数量。
总的数量?
all=m^n (这个一眼就看出来了)
ans=all-num
嗯。那直接乘?但很尴尬的是,这个东东太大了1<=M<=10^8,1<=N<=10^12,明显过不了。
在求 a^n 前
我们可以先求出 a^(n/2)
然后 a^(n/2) * a^(n/2) => a^n
这样一直分割下去,我们能得到一个
O(log(n))的算法,名叫快速幂。
代码如下
#include<cstdio>#include<cstring>using namespace std;typedef long long LL;LL q_mod(LL a,LL b,LL c){ LL ans=1%c;a%=c; while(b) { if(b&1)ans=ans*a%100003; a=a*a%100003;b>>=1; } return ans;}int main(){ LL m,n; scanf("%lld%lld",&m,&n); LL s=((q_mod(m,n,LL(100003))-m*q_mod(m-1,n-1,LL(100003))%LL(100003)+LL(100003))%LL(100003)); printf("%lld\n",s); return 0;}
0 0
- BZOJ1008:[HNOI2008]越狱
- [Bzoj1008][HNOI2008]越狱
- bzoj1008[HNOI2008]越狱
- bzoj1008: [HNOI2008]越狱 数学
- [BZOJ1008][HNOI2008]越狱
- [组合]Bzoj1008 越狱[HNOI2008]
- BZOJ1008[HNOI2008]越狱
- bzoj1008[HNOI2008]越狱
- bzoj1008 [HNOI2008]越狱
- 【HNOI2008】【BZOJ1008】越狱
- BZOJ1008: [HNOI2008]越狱
- BZOJ1008 [HNOI2008]越狱
- bzoj1008: [HNOI2008]越狱
- 越狱[HNOI2008,bzoj1008]
- [bzoj1008][HNOI2008]越狱
- 7.29 bzoj1008 [HNOI2008]越狱
- [BZOJ1008][HNOI2008]越狱
- 【bzoj1008】[HNOI2008]越狱
- 你必须知道的.NET之特性和属性
- 不懂技术不要对懂技术的人说这很容易实现
- pywin32模块安装方法
- 【Leetcode】401. Binary Watch
- 加快Android Studio编译速度 减少gradle时间
- [BZOJ1008][HNOI2008]越狱
- CSS3 小动画
- 23种设计模式之模板方法模式
- 梯度、㪚度、旋度
- 常见的jquery的选择
- C#之WinForm基础 comboBox1.SelectedIndex得到控件中被选中数据项的索引值
- SoapUI Groovy Script
- Android Stduio 下NDK 开发规则
- 输入一行字符,输出最长的单词