bzoj1008: [HNOI2008]越狱(快速幂)

题目传送门
看了数据范围马上想到组合了。。
一开始想直接求方案发现不行。
直接求方案的话应该要容斥原理去重。麻烦!
直接求方案不行就用总方案数-不会越狱的方案数不就完了咯。

总方案数貌似挺好求。
n个格子。每个格子m种选择。
那就是m的n次方。
因为n有点大。快速幂咯。
解决!

不会越狱的方案数。
第一个格子有m种选择。
那么第二种格子为了不跟第一个格子相同,所以有m-1种选择。
后面的格子为了不跟前一个格子相同,也都只有m-1种选择。
所以不会越狱的方案数等于m*(m-1)^(n-1)。
直接快速幂实现。

代码实现:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll mod=100003;
ll pow_mod(ll a,ll b) { //快速幂
    ll ans=1;a%=mod;
    while(b!=0) {
        if(b%2==1)
            ans=(ans*a)%mod;
        b/=2;a=(a*a)%mod;
    }
    return ans;
}
int main() {
    ll m,n;scanf("%lld%lld",&m,&n );
    printf("%lld\n",(((pow_mod(m,n)-(m*pow_mod(m-1,n-1))%mod))%mod+mod)%mod);
    return 0;
}

如果你还往下滚了。
有个要注意的地方:
虽然总方案数一定大于不会越狱的方案数。
但是模了之后就不一定了。
减出来有可能等于负数。要把它转正。
一个负数的转正方法:
(A+mod)%mod(这里mod代表模的数,A代表原数)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值