bzoj 1008 题解

题意简述

有一列长度为nnn的数,每一个数是111~mmm之间的一个数,并且会至少有一对相邻的数相等。求满足这个条件的数列有多少个。

数据

输入
2 3
输出
6

解释

合法的数列为
(1,1,1)(1,1,2)(1,2,2)(2,1,1)(2,2,1)(2,2,2) (1,1,1)\\ (1,1,2)\\ (1,2,2)\\ (2,1,1)\\ (2,2,1)\\ (2,2,2)\\ (1,1,1)(1,1,2)(1,2,2)(2,1,1)(2,2,1)(2,2,2)
666种。

思路

正面想。。。要sisisi啊这什么鬼?暴力枚O(mn)O(m^n)O(mn)然后判???显然不珂以这么干。。。预计得分000分(这珂是省选题啊。。。)
这个时候,听数学老师一句劝永远是最优选择。数学老师曰:

正难则反

我们知道,由刚刚的暴力算法珂知,总情况数是mnm^nmn个。然后我们要求的问题的反面就是:所有相邻的一对数都不相等。
这个珂好考虑多了!!!
确定了第一个(mmm种都珂以)后,剩下的只要保持和上一个不一样就珂以了,无论上一个是什么,现在这一个数都有m−1m-1m1种选择。这样一考虑就是m×(m−1)n−1m\times (m-1)^{n-1}m×(m1)n1种。(注意指数是n−1n-1n1,因为我们特判了第一个有mmm种,就因为这个贡献了一个blingblingblingblingblingblingWAWAWA。)
然后打快速幂就珂以了,别忘了取膜。
代码:

//代码水的我不想写注释。。。
#include<bits/stdc++.h>
#define int long long
#define mod 100003
using namespace std;
int qpow(int a,int p,int m)
{
    a%=m;
    int r=1;
    while(p)
    {
        if (p&1) r=r*a%m;
        a=a*a%m,p>>=1;
    }
    return r;
}

int n,m;
main()
{
    scanf("%lld%lld",&m,&n);
    printf("%lld\n",(qpow(m,n,mod)-m*qpow(m-1,n-1,mod)%mod+mod)%mod);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值