[数学][快速幂] Jzoj P4248 n染色

Description
WYF画了一个极为不规则的n边形,画面太美简直不看,没有任意两条边长度是相等的。因为形状太难看了,做他同桌的CWQ看不下去了,趁着WYF上厕所的时间准备用他书包里的m种颜色的彩笔给n边形的边上色。但由于WYF画的实在太大,CWQ不知如何下手,他想知道他有多少种染色方法,能够使得每两条相邻 边不同色。你只需输出答案模10^9+7的结果。
 
Input
一行,仅包含两个正整数n和m。
Output
一个正整数,表示答案模10^9+7的结果
 
Sample Input
3 3
Sample Output
6
 
Data Constraint
对于50%的数据,3≤n≤100000,3≤m≤10;
对于100%的数据,3≤n≤10^18,3≤m≤50。

 

题解

  • 假设我们有n个点,方案数为A[n]
  • 现在考虑加入第n个点,加入点后左右不同颜色,插入之前的方案数为A[n-1],该点的颜色有m-2中选取的方案
  • 若加入点后左右同色,则删掉一个点后就符合条件了,方案数就为A[n-2],该点的颜色就有m-1种选取的方案
  • 递推公式就是为A[n]=A[n-1]*(m-2)+A[n-2]*(m-1),通项公式为A[n]=(m-1)^n+(m-1)*(-1)^n
  • 递推公式要矩阵乘法加速,通项公式直接快速幂就好了

代码

#include<cstdio>
#define ll long long
#define mo 1000000007
using namespace std;
ll n,m,r;
ll ksm(ll a,ll b) { for (r=1;b;b>>=1,a=a*a%mo) if (b&1) r=r*a%mo; return r; }
int main()
{
    freopen("color.in","r",stdin),freopen("color.out","w",stdout),scanf("%lld%lld",&n,&m);
    printf("%lld\n",(ksm(m-1,n)+(m-1)*ksm(-1,n))%mo);
    return 0;
}

 

转载于:https://www.cnblogs.com/Comfortable/p/10339586.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值