51nod 2379 选择颜色

题目
n个人排成一个环形,每个人要从c种颜色中选择一个。牛牛希望相邻的人选择的颜色是不同的,问有多少种方案。输出方案数对10007取模的结果。
注:人是有顺序的,环旋转同构算不同的方案。

R n m = ( m − 1 ) n + ( m − 1 ) ⋅ ( − 1 ) n R_n^m=(m-1)^n+(m-1)\cdot(-1)^n Rnm=(m1)n+(m1)(1)n这以前老师上课讲的,下面推一下
有递推公式 f n + f n − 1 = c ⋅ ( c − 1 ) n − 1 f_n+f_{n-1}=c\cdot(c-1)^{n-1} fn+fn1=c(c1)n1
右侧很显然,就是第一个位置确定后,依次填后面 n − 1 n-1 n1个位置,且不管第一个位置与最后一个位置的颜色是否相同
最后一个与第一个颜色相同,那么与第二个颜色必不同,那就可以把第一个抠掉,即 f n − 1 f_{n-1} fn1
与第一个颜色不同,那符合 f n f_n fn的条件,那么左侧显而易见
下面就简单了 f n − 1 + f n − 2 = c ⋅ ( c − 1 ) n − 2 f_{n-1}+f_{n-2}=c\cdot(c-1)^{n-2} fn1+fn2=c(c1)n2
两式相减,得 f n − f n − 2 = c ⋅ ( c − 1 ) n − 2 ⋅ ( c − 2 ) f_n-f_{n-2}=c\cdot(c-1)^{n-2}\cdot(c-2) fnfn2=c(c1)n2(c2)
再加下一式,减下下式……以此类推
正着做就这么做,倒着的话数规就行了,也方便

#include<bits/stdc++.h>
using namespace std;
const int M=10007;
int n,m;
int pw(int x,int y){
	int z=1;
	for (;y;y>>=1,x=x*x%M)
		if (y&1) z=z*x%M;
	return z;
}
int main(){
	scanf("%d%d",&n,&m);
	printf("%d",pw(m-1,n)+(n&1?-1:1)*(m-1));
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值