zoukankan      html  css  js  c++  java
  • [HNOI2008]越狱(思路+题解)

    快速幂+组合数学

    题目链接https://www.luogu.org/problemnew/show/P3197

    题目大意:N个格子,用M个数字填,且必须填满,求出相邻格子中数字一样的方案数,输出结果对100003取余。

    输入样例:

    2 3

    输出样例

    6

    样例解释

    6种状态为(000)(001)(011)(100)(110)(111)

    数据范围

    1M10^8
    1≤N≤10^12

    解题思路:一开始我是想的看能不能套组合的公式,然而并没有套出来,然后就去思考每一个格子能够填数字的方案数。

    但是如果正面去做的话,方案数很多,没有办法考虑全,那就容斥一下就行了,正难则反嘛...

    于是问题就变成了求出相邻格子中的数字不一样的方案数,第一个格子的方案数为M,它什么都可以填,

    第二个格子的数为了保证与第一个数不同,方案数为M-1,不难发现,之后的每个格子的方案数都为M-1,

    所以根据乘法原理,不合法的方案数为M*(M-1)^(n-1)。而总的方案数怎么算呢?很简单,每个格子都可以填M个中的任意一个数字,即总方案数为M^n。

    我们要输出的答案就是M^n-M*(M-1)^(n-1),当然,还要取模。

    N和M的范围很大,所以用快速幂解决。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define ll long long int
    using namespace std;
    ll n,m,ans,mod=100003;
    ll power(ll b,ll p){
        ll tot=1;
        while(p){
            if(p&1){
            tot=(tot*b)%mod;
            }
            p>>=1;
            b=(b*b)%mod;
        }
        return tot%mod;
    }
    int main()
    {
        scanf("%lld%lld",&m,&n);
        ans=(power(m,n)%mod-(m*power(m-1,n-1))%mod+mod)%mod;
        printf("%lld",ans%mod);
        return 0;
    }
  • 相关阅读:
    第二阶段冲刺—第三天
    团队测试计划
    第二阶段冲刺—第二天
    第二阶段冲刺—第一天
    评分表
    针对每个组建议的改进
    第二阶段团队绩效评分
    项目总结
    会议2.10
    会议2.9
  • 原文地址:https://www.cnblogs.com/sky-zxz/p/9510475.html
Copyright © 2011-2022 走看看